我编写的的一个用于复制文件夹的Java方法出现了问题:文件拒绝访问

我编写了一个copyDir的方法来复制文件夹,它需要传入目标文件夹的File对象和源文件夹的File对象,这个方法还调用了我编写的obstructiveCopyFile方法和obstructiveCopyDir方法,这段代码在被调用时会因为"拒绝访问"而抛出FileNotFoundException,我传入的源文件对象也是一个存在的有效文件夹,里面包含多个子目录

下面就是有问题的java代码

public String obstructiveCopyFile(File sourceFile, File targetFile) throws IOException {
        final String[] Message = new String[1];
        final Long[] time = new Long[1];

        Long startTime = System.currentTimeMillis();
        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(sourceFile));
        Integer c;
        String FileName = sourceFile.getName();
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream
                (new FileOutputStream(targetFile + "\\" + FileName));
        byte[] bin = new byte[1024];
        while ((c = bufferedInputStream.read(bin)) != -1) {
            bufferedOutputStream.write(bin, 0, c);
        }
        bufferedOutputStream.flush();
        bufferedInputStream.close();
        bufferedOutputStream.close();
        time[0] = (System.currentTimeMillis() - startTime);
        Message[0] = "复制完成 ,文件名:" + sourceFile.getName() +
                ", 文件大小:" + sourceFile.length() + "字节" + ", 耗时:" + time[0] + "ms";
        return Message[0];
    }

    public void obstructiveCopyDir(File dirSource, File targetFile) throws IOException {

        final String[] Message = new String[1];
        final Long[] time = new Long[1];
        final File[] dirs = new File[1];
        dirs[0] = dirSource;
        if (!dirs[0].isDirectory()) {
            return;
        }
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        }
        File[] files = dirs[0].listFiles();
        for (File file : files) {
            if (file.isFile()) {
                File newFile = new File(targetFile, file.getName());
                obstructiveCopyFile(new File(trimFilePath(file.toPath().toString()) + "\\"),
                        new File(trimFilePath(newFile.toPath().toString()) + "\\"));
            } else if (file.isDirectory()) {
                File newDestinationFolder = new File(targetFile, file.getName());
                copyDir(file, newDestinationFolder);

            }
        }
    }
    
    public void copyDir(File dirSource, File targetFile) {
        final String[] Message = new String[1];
        final Long[] time = new Long[1];
        Thread copyDirThreed = new Thread(new Runnable() {
            @Override
            public void run() {
                if (!dirSource.isDirectory()) {
                    return;
                }
                if (!targetFile.exists()) {
                    targetFile.mkdirs();
                }
                File[] files = dirSource.listFiles();
                for (File file : files) {
                    if (file.isFile()) {
                        File newFile = new File(targetFile, file.getName());

                        try {
                            obstructiveCopyFile(new File(trimFilePath(file.toPath().toString()) + "\\"),
                                    new File(trimFilePath(newFile.toPath().toString()) + "\\"));
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }

                    }
                    if (file.isDirectory()) {
                        File newDestinationFolder = new File(targetFile, file.getName());
                        try {
                            obstructiveCopyDir(file, newDestinationFolder);


                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }

            }


        }, "copyDirThreed");
        copyDirThreed.start();


    }

最开始我认为时因为copy相关方法都使用了多线程来进行文件IO操作导致的线程不同步问题,但我将copy相关方法都添加了一个单线程阻塞IO版本后(也就是obstructiveCopyFile和obstructiveCopyDir,改为单线程版本后内部逻辑没变),我在copyDir方法中都调用了这些obstructive方法,但没有解决问题

我经过断点调试,发现在copyDir中调用obstructiveCopyFile时直接传入了一个文件夹对象导致原本只能复制单文件的obstructiveCopyFile方法错误的复制了一个文件夹,因此才会因为拒绝访问而抛出FileNotFoundException,但是我在copyDir和obstructiveCopyDir都做了判断,只有当在当前目录下文件列表中遍历出的文件是单个普通文件时才会调用copyFile方法,否则循环调用obstructiveCopyDir,我不知道为什么会出错

权限不足,用管理员权限试试看

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    首先,需要检查obstructiveCopyFile方法是否正确的处理了文件和文件夹的区别。由于你误传了一个文件夹对象而导致错误的复制了一个文件夹,说明obstructiveCopyFile方法并没有正确地区分文件和文件夹。

    接下来,我将给出一个修复的方案,你可以尝试将以下代码添加到你的copyDir方法中:

    private void copyDir(File source, File destination) throws IOException {
        // 首先检查目标文件夹是否存在,如果不存在则先创建它
        if (!destination.exists()) {
            destination.mkdir();
        }
    
        // 遍历源文件夹中的所有文件和文件夹
        for (File file : source.listFiles()) {
            // 如果是文件,则调用obstructiveCopyFile方法进行复制
            if (file.isFile()) {
                obstructiveCopyFile(file, new File(destination, file.getName()));
            }
            // 如果是文件夹,则调用obstructiveCopyDir方法进行复制
            else if (file.isDirectory()) {
                obstructiveCopyDir(file, new File(destination, file.getName()));
            }
        }
    }
    

    在这个修复方案中,我们确保了obstructiveCopyFile方法只会被调用一次,并且只会传入正确的文件对象。同时,我们也将文件夹的复制过程封装到了新的方法obstructiveCopyDir中,以确保文件夹的复制也是正确的。

    这样,你应该能够解决"文件拒绝访问"错误并正确地复制文件夹了。如果还有其他问题,请随时追问。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^