Context.openFileInput 和 Context.openFileOutput 之间的同步

Synchronization between Context.openFileInput and Context.openFileOutput

我有一个 Android Service 运行ning 每天做一些数据同步。每天一次,它通过 context.openFileOutput:

下载文件并将其缓存到磁盘
String fileName = Uri.parse(url).getLastPathSegment();
try (FileOutputStream outputStream =
     context.openFileOutput(fileName, Context.MODE_PRIVATE)) {
   outputStream.write(bytes);
   // ...
} catch (IOException e) {
   // logging ...
}

这发生在 后台 线程上。 我还有一个 UI,其中包含一个 WebViewWebView 使用那些缓存的资源,如果它们可以通过 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);
}

这发生在独立于服务的另一个后台线程上。

我能否依靠 Context 实施并确保文件读写安全,还是我必须自己处理同步? 例如。如果 Service 当前正在将数据写入文件而 WebView 正在尝试访问它,我 运行 会不会遇到问题?如果是这样,我应该如何实现同步?

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

在这种情况下,您可以通过在文件名后附加一些内容并在下载完成后改回文件名来将数据写入文件。例如

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

稍后在下载完成后将文件重命名为原始文件 fileName。我确定您会检查 shouldUseCache(url) 中的文件是否存在,因此它会继续正常工作。这将避免在您尝试阅读文件时文件仍在下载的情况。