Thursday, June 28, 2018

Synchronization between Context.openFileInput and Context.openFileOutput

Leave a Comment

I have an Android Service running daily which does some data synchronization. Once a day it downloads a file and caches it to disk via context.openFileOutput:

String fileName = Uri.parse(url).getLastPathSegment(); try (FileOutputStream outputStream =      context.openFileOutput(fileName, Context.MODE_PRIVATE)) {    outputStream.write(bytes);    // ... } catch (IOException e) {    // logging ... } 

This happens on a background thread. I also have a UI which contains a WebView. The WebView uses those cached resources if they are available via context.openFileInput:

@Override public WebResourceResponse shouldInterceptRequest(     WebView view, WebResourceRequest request) {   String url = request.getUrl().toString();   if (shouldUseCache(url)) {      try {         return new WebResourceResponse(              "video/webm",              Charsets.UTF_8.name(),              context.openFileInput(obtainFileName(url)));      } catch (IOException e) {        // If a cached resource fails to load, just let the WebView load it the normal way.        // logging ...      }   }   return super.shouldInterceptRequest(view, request); } 

This happens on another background thread independently from the service.

Can I rely on Context implementation and be sure that file reads and writes are safe, or do I have to take care of the synchronization myself? E.g. if the Service is currently writing data to a file and the WebView is trying to access it, will I run into a problem? If so, how should I implement the synchronization?

1 Answers

Answers 1

If the Service is currently writing data to a file and the WebView is trying to access it, will I run into a problem?

In such cases you can write data to a file by appending something to file name and changing its name back once download is finished. e.g.

context.openFileOutput(fileName + ".downloading", Context.MODE_PRIVATE))

and later once download is finished rename the file to original fileName. I am sure you check for file presence in shouldUseCache(url) so it will keep working normally. This will avoid situations where a file is still downloading while you try to read it.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment