Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 复制的文件已损坏_Java_Android_File_Corruption - Fatal编程技术网

Java 复制的文件已损坏

Java 复制的文件已损坏,java,android,file,corruption,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 outStr

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

这是通过输入路径返回文档文件的方法

 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;
 }
publicstaticdocumentfile getDocumentFileIfAllowedToWrite(文件文件,上下文con){
List permissionUris=con.getContentResolver().getPersistedUrmissions();
for(UriPermission permissionUri:permissionUri){
Uri treeUri=permissionUri.getUri();
DocumentFile rootDocFile=DocumentFile.fromTreeUri(con,treeUri);
字符串rootDocFilePath=“SD卡路径”;
if(file.getAbsolutePath().startsWith(rootDocFilePath)){
ArrayList pathInRootDocParts=新的ArrayList();
而(!rootDocFilePath.equals(file.getAbsolutePath())){
pathInRootDocParts.add(file.getName());
file=file.getParentFile();
}
DocumentFile docFile=null;
if(pathInRootDocParts.size()==0){
docFile=DocumentFile.fromtreeeuri(con,rootDocFile.getUri());
}否则{
对于(int i=pathInRootDocParts.size()-1;i>=0;i--){
if(docFile==null){
docFile=rootDocFile.findFile(pathInRootDocParts.get(i));
}否则{
docFile=docFile.findFile(pathInRootDocParts.get(i));
}
}
}
if(docFile!=null&&docFile.canWrite()){
返回文档文件;
}否则{
返回null;
}
}
}
返回null;
}

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

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

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

冲水

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

outStream.getFD().sync()

默认情况下,文件系统写入和读取由操作系统缓存。这不会影响您,除非您在复制()后的确切时刻取下电池

这里已经解释了更多


为什么不使用
文件。复制(源、目标、替换现有)?@sarkasronie不使用此方法的原因是应用程序可能不仅将数据传输到同一存储器,还将数据传输到可移动SD卡。从Android 5.0及以上版本开始,必须使用存储访问框架将数据传输到可移动存储。
public static boolean copy(文件副本,字符串目录,
请从一个调用此函数的示例开始。我们想查看所有完整路径。请将示例放在您的帖子中。@greenapps抱歉。我已经添加了信息。请您看一看。Android不太常用,但
mime=“application/octet stream”;
(二进制数据)我本以为会的。谢谢你的回答。但是这个问题的代码几乎与原始海报上发布的代码相同,很少复制损坏的文件。有什么原因吗?谢谢@Rahulrr2602提供赏金。我更新了答案,希望现在能更好地解释。谢谢你的反馈。拉杰什K,不,你不必,只有佛罗里达州ush是必需的。当您想要强制文件系统同步时,会有一些用例,但我不认为是这种情况。而且这不仅仅是特定于输出/输入流的java实现,这是一种更普遍的做法。Rajesh K,但当我再次思考时,它应该是必需的。因为您正在复制到可移动SD卡。所以想象一下ario当您的应用程序指示复制已完成,并且用户在复制完成后立即删除卡时。很简单,因为人们可能认为复制已完成,同步应将您保存在此处。这类似于windows“安全删除可移动驱动器”。但它的作用是iz确保文件系统缓存已同步。