Android Marshmallow:SAF编写的文件不会立即写入

我正在使用SAF(存储访问框架)将文件写入SD卡.在Marshmallow上,文件实际上是以大延迟(大约10秒)写入和更新的.

当我使用例如:

android.support.v4.provider.DocumentFile docFile = DocumentFile.fromTreeUri(context, getUri()) // tree uri that represents some existing file on sd card
File file = getFile(getUri()); // java.io.File that points to same file as docFile

docFile.length(); // length of current file is e.g. 150B
file.length(); // length of file is also 150B
try (OutputStream outStream = context.getContentResolver().getOutputStream(docFile.getUri()))
{
   outStream.write(data, 0, 50); // overwrite with 50 B
   outStream.flush(); // didn't help
}

docFile.length(); // it still returns 150B !!
file.length(); // it still returns 150B

Thread.sleep(12000); // sleep 12 seconds

docFile.length(); // now it returns  correctly 50B
file.length(); // now it returns  correctly 50B

顺便说一句.当我通过File.length()方法检查长度时,它返回相同的值.

有没有办法立即写出来?或者我可以设置一些听众?否则我必须定期检查尺寸,我不想这样做.实际上,我不想在写入文件后等待10秒.

最佳答案 所以我发现当我同时使用java.io.File和SAF api时会出现延迟.通过File.isDirectory(),File.exists(),File.length()方法检查文件会导致后续调用

context.getContentResolver().getOutputStream(someUri))

延迟了10秒钟.它也延迟了删除.即当你尝试:

DocumentFile docFile = DocumentFile.fromTreeUri(context, someUri);
File file = new File("path to same file as someUri");
if(file.exists() && !file.isDirectory()) // this cause the delay
{
  docFile.delete();
}

boolean exists = file.exists(); // exists is INCORRECTLY true
exists = docFile.exists(); // exists is INCORRECTLY true

Thread.sleep(12000);

exists = file.exists(); // exists is CORRECTLY false
exists = docFile.exists(); // exists is CORRECTLY false

我使用File类进行只读操作,因为它更快.但自Marshmallow以来,我无法与SAF一起使用它.它必须严格使用SAF api:

DocumentFile docFile = DocumentFile.fromTreeUri(context, someUri);
if(docFile.exists() && !docFile.isDirectory()) // this cause the delay
{
  docFile.delete();
}

boolean exists = docFile.exists(); // exists is CORRECTLY false
点赞