无法将文件复制到文件夹

Can't copy files to a folder

任务: 我想将所选文件从 A 文件夹复制到 B 文件夹。这两个文件夹都在外部存储中。

问题:它工作得很好,但是,在某些时候它只是停止复制文件。比如我要复制500个文件,它只会复制110个文件。我还注意到我无法复制视频文件,它只能用于图像。

代码:

我复制文件的方法:

  private static void makeFileCopy(File source, File dest) throws IOException {
    InputStream is = null;
    OutputStream os = null;
    try {
        is = new FileInputStream(source);
        os = new FileOutputStream(dest);
        byte[] buffer = new byte[1024];
        int length;
        while ((length = is.read(buffer)) > 0) {
            os.write(buffer, 0, length);
        }
    }finally {
        try {
            if (is != null)
                is.close();
            if (os != null)
                os.close();
        }catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

还有一个:

 public static void copyFileList(Context context, List<MediaFile> contentList, File mediaFolder) {
    if (contentList != null) {
        ContentValues values=new ContentValues();
        for (int index=0;index<contentList.size();index++) {
            MediaFile mediaFile=contentList.get(index);
            File file = new File(mediaFolder, mediaFile.mediaFile().getName());
            boolean isVideo=mediaFile.getType()== MediaFile.Type.VIDEO;
            if (!file.exists()) {
                try {
                    if (!file.createNewFile()) {
                        continue;
                    }
                    FileUtils.makeFileCopy(mediaFile.getRealFile().getAbsoluteFile(), file);

                } catch (IOException ex) {
                    ex.printStackTrace();
                    continue;
                }

                if (isVideo) {
                    values.put(MediaStore.Video.VideoColumns.DATA, file.getAbsolutePath());
                    context.getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
                } else {
                    values.put(MediaStore.Images.ImageColumns.DATA, file.getAbsolutePath());
                    context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
                }
                values.clear();
            }
        }
    }
}

谢谢!

终于,我解决了那个问题。这是我犯的极其愚蠢的错误。

解决方案: 我想复制目标文件夹中已有的文件,但通过检查 if (!file.exists()) 它没有通过。所以,我想出了以下代码:

public static void copyFileList(Context context, List<MediaFile> contentList, File mediaFolder) {
    if (contentList != null) {
        ContentValues values=new ContentValues();
        for (int index=0;index<contentList.size();index++) {
            MediaFile mediaFile=contentList.get(index);
            String fileName=mediaFile.mediaFile().getName();

            boolean isVideo=mediaFile.getType()== MediaFile.Type.VIDEO;
            File file = new File(mediaFolder, fileName);
            //let a user to decide whether to create a copy of already existing files
            if(!file.exists()) {
                file=new File(mediaFolder,uniqueNameFor(fileName));
            }

            if(!file.exists()) {
                try {
                    FileUtils.makeFileCopy(mediaFile.mediaFile().getAbsoluteFile(), file);
                } catch (IOException ex) {
                    ex.printStackTrace();
                    continue;
                }

                if (isVideo) {
                    values.put(MediaStore.Video.VideoColumns.DATA, file.getAbsolutePath());
                    values.put(MediaStore.Video.VideoColumns.MIME_TYPE,mediaFile.getMimeType());
                    context.getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
                } else {
                    values.put(MediaStore.Images.ImageColumns.DATA, file.getAbsolutePath());
                    values.put(MediaStore.Images.ImageColumns.MIME_TYPE,mediaFile.getMimeType());
                    context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
                }

            }
            values.clear();
        }
    }
}

只需创建一个唯一的文件名。

我也确实更改了复制方法:

   private static void makeFileCopy(File source, File dest) throws IOException {
    FileChannel inputChannel = null;
    FileChannel outputChannel = null;
    try {
        inputChannel = new FileInputStream(source).getChannel();
        outputChannel = new FileOutputStream(dest).getChannel();
        outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
    } finally {
        try {
            if (inputChannel != null)
                inputChannel.close();
            if (outputChannel != null)
                outputChannel.close();
        }catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

使用通道比使用以前的方法要快一点。 查看复制文件的 4 种方法 here.

感谢您的帮助!