复制的文件已损坏

Files copied are corrupted

我正在尝试传输 Android 中的一些文件。

我有文件列表,然后将它们传输到所需位置。

文件类型可以是任何图像、视频、音频、Gif、PowerPoint、Word 等

文件列表的大小在 100 左右。

这是我用来传输文件的代码

public static boolean copy(File copy, String directory, Context con) {
   static FileInputStream inStream = null;
   static OutputStream outStream = null;
   DocumentFile dir = getDocumentFileIfAllowedToWrite(new File(directory), con);
   String mime = "";
   DocumentFile copy1 = dir.createFile(mime, copy.getName());

   try {
      inStream = new FileInputStream(copy);
      outStream = con.getContentResolver().openOutputStream(copy1.getUri());
      byte[] buffer = new byte[16384];
      int bytesRead;
      while ((bytesRead = inStream.read(buffer)) != -1) {
         outStream.write(buffer, 0, bytesRead);
      }
   }
   catch (FileNotFoundException e) {
      e.printStackTrace();
   } catch (IOException e) {
      e.printStackTrace();
   } finally {
      try {
         inStream.close();
         outStream.close();
         return true;
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
   return false;
}

谁能解释一下传输后文件损坏的原因以及可以采取的预防措施。

编辑:这就是我使用函数的方式

String from = "/storage/emulated/0/Pictures/IMG.jpg";
String to = "/storage/3096-13FF/Pictures";

Class.copy(from, to, this);

编辑 2:原始文件大小平均约为 1-2 MB。 复制的文件大小 = 未知,因为此问题已由用户提出。

这是通过输入路径return一个DocumentFile的方法。

 public static DocumentFile getDocumentFileIfAllowedToWrite(File file, Context con) {

List<UriPermission> permissionUris = con.getContentResolver().getPersistedUriPermissions();

for (UriPermission permissionUri : permissionUris) {

    Uri treeUri = permissionUri.getUri();
    DocumentFile rootDocFile = DocumentFile.fromTreeUri(con, treeUri);
    String rootDocFilePath = "SD CARD PATH";
    if (file.getAbsolutePath().startsWith(rootDocFilePath)) {

        ArrayList<String> pathInRootDocParts = new ArrayList<String>();
        while (!rootDocFilePath.equals(file.getAbsolutePath())) {
            pathInRootDocParts.add(file.getName());
            file = file.getParentFile();
        }

        DocumentFile docFile = null;

        if (pathInRootDocParts.size() == 0) {
            docFile = DocumentFile.fromTreeUri(con, rootDocFile.getUri());
        } else {
            for (int i = pathInRootDocParts.size() - 1; i >= 0; i--) {
                if (docFile == null) {
                    docFile = rootDocFile.findFile(pathInRootDocParts.get(i));
                } else {
                    docFile = docFile.findFile(pathInRootDocParts.get(i));
                }
            }
        }
        if (docFile != null && docFile.canWrite()) {
            return docFile;
        } else {
            return null;
        }

    }
}
return null;
 }

我让用户使用存储访问框架选择 SD 卡目录,这样我就可以写入 SD 卡中的任何目录。然后,每当必须传输文件时,我都会让用户使用自定义对话框选择路径。

数据在实际写入之前由 OtputStream 缓冲,而不是直接写入文件。在您关闭文件时,一些数据可能仍保留在此缓冲区中。这是提高小型写入性能的优化,它消除了由缓慢的持久性存储设备(如硬盘、SD 卡)引起的大量延迟....

您需要在关闭文件之前刷新输出流缓冲区。我认为所有数据都没有同步到文件。所以在关闭输出之前,尝试刷新缓冲区。

outStream.flush();

并确保数据从文件系统缓存写入存储设备(SD 卡),(如果不是由 close() 隐式完成)

outStream.getFD().sync();

默认情况下,文件系统写入和读取由操作系统缓存。这应该不会影响你,除非你在 copy()

之后的确切时刻取出电池

更多信息已在此处解释

I/O concept flush vs sync