[java.io.File.length()当实际文件为0字节时大于0

问题描述 投票:0回答:1

What:

我的Android应用程序正在压缩已root用户的Android设备(API 25+)上的目录,并将zip写入可移动USB记忆棒。

问题:

Java告诉我该文件为97,993字节,但是当我从Android设备中取出USB记忆棒并将其插入我的mac时,mac表示它为0字节。

代码:

/// Where is the directory that we're compressing onto the USB stick?
File dir = new File(Environment.getExternalStorageDirectory(), "logs");
if (!dir.exists() || !dir.isDirectory()) throw new IOException("Invalid directory.");

/// Where on the USB stick is the logs.zip going to go?
File zip = new File("/storage/FD91-1317/logs.zip");

/// Delete the file if it already exists then recreate it 
if (zip.exists() && !zip.delete()) throw new IOException("Failed to create zip file.");
zip.createNewFile();

/// Using try {} to manage our streams
try (FileOutputStream fileOutputStream = new FileOutputStream(zip); ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream)) {
    /// Get the list of files to enumerate through
    File[] files = dir.listFiles();

    // Enumerate through each file to be compressed
    for (File file : files) {
        /// If somehow a file was deleted throw an exception
        if (!file.exists()) throw new FileNotFoundException(file.getPath());

        /// Create the new zip entry
        zipOutputStream.putNextEntry(new ZipEntry(file.getName()));

        /// Copy the file into the zip
        try (FileInputStream fileInputStream = new FileInputStream(file)) {
            IOUtils.copy(fileInputStream, zipOutputStream);
        }

        /// Close the zip entry
        zipOutputStream.closeEntry();
    }
}

/// Validate that the zip has been created successfully 
if (zip.length() == 0) throw new IOException("Zip failed to be created!!!!");
Log.v("logs", String.format("Logs collected: %s", zip.length());

更多信息:

  • 我的应用程序正在/system/priv-app/目录中作为系统应用程序运行
  • 我的应用程序具有android.permission.WRITE_MEDIA_STORAGE权限
  • 如果我在调用Log.v(...)后5-10秒钟内拔出USB记忆棒,则将其插入Mac时,USB记忆棒上的zip文件只有0个字节。如果我等待超过10秒,它将始终有字节。
  • [Log.v(...)也在记录Logs collected: 97993
  • org.apache.commons.io.FileUtils.readFileToByteArray(zip)还将返回一个长度为97993的字节数组,并且该字节数组100%中包含数据,并且不为空。
  • [ls -l /storage/FD91-1317也表示logs.zip为97993字节。

Closing:

我已经尝试了所有可以想到的一切,但是仍然无法弄清Java为什么说zip包含数据,但是当插入我的mac时说的是文件为0字节。 Windows告诉我同样的事情。我所知道的唯一事实是,如果我等了10秒钟以上才从Android设备上拔下USB,则不会发生此问题,但我担心,取决于zip的大小,可能时间不够在所有情况下。据我所知,一旦您写入流并关闭它,它应该100%完成。

java android java-io
1个回答
1
投票

为了解决该问题,我必须运行fileOutputStream.getFD().sync();如果有人想知道已修复它的why运行,下面是Java文档的摘录,解释sync();的作用。

enter image description here

请参阅:https://docs.oracle.com/javase/7/docs/api/java/io/FileDescriptor.html#sync()以获取更多详细信息。


非常感谢@CommonsWare的协助!

© www.soinside.com 2019 - 2024. All rights reserved.