2013-02-10 3 views
3

Я создаю приложение, которое должно читать данные из файла. Сначала я читал его из папки с ресурсами, используя BufferedReader и InputStreamReader, но у меня возникали проблемы с памятью (см. Android: File Reading - OutOfMemory Issue). Одно из предложений заключалось в том, чтобы скопировать данные из папки активов во внутреннее хранилище (, а не на карту SD), а затем получить доступ к ней через RandomAccessFile. Так что я посмотрел, как копировать файлы из активов в внутреннюю память, и я нашел 2 источников:Android: доступ к файлу из внутреннего хранилища с использованием RandomAccessFile

https://groups.google.com/forum/?fromgroups=#!topic/android-developers/RpXiMYV48Ww

http://developergoodies.blogspot.com/2012/11/copy-android-asset-to-internal-storage.html

Я решил использовать код из второго и модифицировал его для моего файла , Это выглядит так:

public void copyFile() { 
    //Open your file in assets 
    Context context = getApplicationContext(); 
    String destinationFile = context.getFilesDir().getPath() + File.separator + "text.txt"; 

    if (!new File(destinationFile).exists()) { 
     try { 
      copyFromAssetsToStorage(context, "text.txt", destinationFile); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

private void copyStream(InputStream input, OutputStream output) throws IOException { 
    byte[] buffer = new byte[1024]; 
    int length = Input.read(buffer); 
    while (length > 0) { 
     output.write(buffer, 0, length); 
     length = input.read(buffer); 
    } 
} 

private void copyFromAssetsToStorage(Context context, String sourceFile, String destinationFile) throws IOException { 
    InputStream inputStream = context.getAssets().open(sourceFile); 
    OutputStream outputStream = new FileOutputStream(destinationFile); 
    copyStream(inputStream , outputStream); 
    outputStream.flush(); 
    outputStream.close(); 
    inputStream.close(); 
} 

Я предполагаю, что это копирует файл в каталог данных приложения. Я не смог проверить его, потому что хотел бы получить доступ к файлу с помощью RandomAccessFile. Тем не менее, я никогда не делал ни одного из этих двух (копирование файла из активов и RandomAccessFile), поэтому я застрял. Работа над этим приложением зашла в тупик, потому что это единственное, что мешает мне завершить его.

Может ли кто-нибудь предоставить мне исправления, предложения и правильную реализацию способов доступа к данным с помощью RandomAccessFile? (Данные список строк 4-15 символов в длину на каждой строке.)

EDIT *

private File createCacheFile(Context context, String filename){ 
File cacheFile = new File(context.getCacheDir(), filename); 

    if (cacheFile.exists()) { 
     return cacheFile ; 
    } 

    InputStream inputStream = null; 
    FileOutputStream fileOutputStream = null; 

    try { 

     inputStream = context.getAssets().open(filename); 
     fileOutputStream = new FileOutputStream(cacheFile); 

     int bufferSize = 1024; 
     byte[] buffer = new byte[bufferSize]; 
     int length = -1; 
     while ((length = inputStream.read(buffer)) > 0) { 
      fileOutputStream.write(buffer,0,length); 
     } 

    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    finally { 
     try { 
      fileOutputStream.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     try { 
      inputStream.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    return cacheFile; 
} 

ответ

1

1- Скопируйте файл из активов в каталоге кэша

Этот код просто для иллюстрации, вы должны сделать соответствующие обработку исключений и близких ресурсов

private File createCacheFile(Context context, String filename){ 
    File cacheFile = new File(context.getCacheDir(), filename); 

    if (cacheFile.exists()) { 
     return cacheFile ; 
    } 


    InputStream inputStream = context.getAssets().open(filename); 
    FileOutputStream fileOutputStream = new FileOutputStream(cacheFile); 

    int bufferSize = 1024; 
    byte[] buffer = new byte[bufferSize]; 
    int length = -1; 
    while ((length = inputStream.read(buffer)) > 0) { 
    fileOutputStream.write(buffer,0,length); 
    } 

    fileOutputStream.close(); 
    inputStream.close(); 

    return cacheFile; 
} 

2- Откройте файл с помощью RandomAccessFile

File cacheFile = createCacheFile(context, "text.txt"); 
RandomAccessFile randomAccessFile = new RandomAccessFile(cacheFile, "r"); 

// Process the file 

randomAccessFile.close();  

На стороне записки, вы должны следовать Java именования, например, Ваш метод и имя переменной должно начинаться с маленькой буквы, такие как copyFromAssetsToStorage и destinationFile

Edit:

Вы должны сделать отдельный try/catch для каждой close() операции, так что если один выходит из строя другие по-прежнему получают казнены и убедитесь, что они не являются null

finally { 
    try { 
     if(fileOutputStream!=null){ 
      fileOutputStream.close();    
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    try { 
     if(inputStream!=null){ 
     inputStream.close();  
     }  
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 
+0

Спасибо за ваш ответ. Я хочу убедиться, что я прав. Правильно ли я использовал try/catch (см. Править)? Ошибок нет, но это не обязательно означает, что это правильно. Кроме того, мне нужно делать какие-либо «очистки», такие как очистка кеша после каждого использования? –

+0

Вы должны определить 'fileOutputStream' и' inputStream' вне блока 'try/catch' и закрыть их в блоке' final' после проверки того, что они не являются нулевыми (вам понадобится еще один 'try/catch' для каждого' close () 'операция) – iTech

+0

Вау ... э-э ... хорошо. Я предполагаю, что все должно быть в другом потоке?В настоящее время у меня установлен асинхронный поток, так что я бы просто получил код шага 2 в методе doInBackground класса async? –

Смежные вопросы