Android: Accessing File from Internal Storage Usin

2020-04-11 07:48发布

I am creating an app that needs to read data from a file. I was initially reading it from the assets folder using a BufferedReader and an InputStreamReader but I was running into memory issues (see Android: File Reading - OutOfMemory Issue). One suggestion was to copy the data from the assets folder to the internal storage (not the SD card) and then access it via RandomAccessFile. So I looked up how to copy files from the assets to internal storage and I found 2 sources:

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

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

I decided to use the code from the second one and modified it for my file. So it looks like this:

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();
}

I am assuming that this copies the file into the app's data directory. I have not been able to test it because I would like to be able to access the file using RandomAccessFile. However, I have never done either one of these two (copying the file from assets and RandomAccessFile) so I am stuck. The work on this app has come to a standstill because this is the only thing that is preventing me from completing it.

Can anyone provide me with corrections, suggestions, and correct implementations of how to access the data using RandomAccessFile? (The data is a list of strings 4-15 characters in length on each line.)

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条回答
走好不送
2楼-- · 2020-04-11 08:26

1- Copy the file from assets to the cache directory

This code just for illustration, you have to do appropriate exception handling and close resources

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- Open the file using RandomAccessFile

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

// Process the file

randomAccessFile.close();    

On a side note, you should follow Java naming conventions, e.g. your method and variable name should start with small letter such as copyFromAssetsToStorage and destinationFile

Edit:

You should make a separate try/catch for each close() operation, so if one fails the other still get executed and check that they are not null

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

    try {
      if(inputStream!=null){
       inputStream.close();      
      }      
    } catch (IOException e) {
        e.printStackTrace();
    }
}  
查看更多
登录 后发表回答