复制的文件已损坏

时间:2018-03-16 11:49:31

标签: java android file corruption

我正在尝试在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。         复制的文件大小=未知,因为用户已提出此问题。

这是通过输入路径返回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卡中的任何目录。然后,当文件必须传输时,我正在让用户使用自定义对话框选择路径。

1 个答案:

答案 0 :(得分:3)

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

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

outStream.flush();

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

outStream.getFD()同步();

通过defult,文件系统写入和读取由操作系统缓存。除非您在复制()

后的确切时刻取出电池,否则这不会对您造成影响

此处已详细说明了

I/O concept flush vs sync