在Java中将文件从一个目录复制到另一个目录

182
我想使用Java从一个目录复制文件到另一个目录(子目录)。我有一个名为dir的目录,其中包含文本文件。我迭代dir中的前20个文件,并希望将它们复制到dir目录中的另一个目录(trainingDir),在迭代之前我已经创建了这个目录。
在代码中,我想将review(表示第i个文本文件或评审)复制到trainingDir。我该怎么做?似乎没有这样的函数(或者我找不到)。谢谢。
在代码中,我需要将review(表示第i个文本文件或review)复制到trainingDir中。请问有什么方法可以实现吗?我尝试查找相关函数但未果。谢谢。
boolean success = false;
File[] reviews = dir.listFiles();
String trainingDir = dir.getAbsolutePath() + "/trainingData";
File trDir = new File(trainingDir);
success = trDir.mkdir();
for(int i = 1; i <= 20; i++) {
    File review = reviews[i];

}

所以,您有一个充满文件的目录,并且您只想复制这些文件吗?输入端没有递归 - 例如将所有内容从子目录复制到主目录? - akarnokd
是的,没错。我对将这些文件复制或移动到另一个目录都很感兴趣(尽管在帖子中我只问了复制)。 - user42155
3
未来的更新:Java 7 版本增加了 Files 类中的一个特性,可以用于复制文件。这里有另一篇相关的帖子 https://dev59.com/qWQn5IYBdhLWcg3w9bCi。 - KevinL
34个回答

0
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class CopyFiles {
    private File targetFolder;
    private int noOfFiles;
    public void copyDirectory(File sourceLocation, String destLocation)
            throws IOException {
        targetFolder = new File(destLocation);
        if (sourceLocation.isDirectory()) {
            if (!targetFolder.exists()) {
                targetFolder.mkdir();
            }

            String[] children = sourceLocation.list();
            for (int i = 0; i < children.length; i++) {
                copyDirectory(new File(sourceLocation, children[i]),
                        destLocation);

            }
        } else {

            InputStream in = new FileInputStream(sourceLocation);
            OutputStream out = new FileOutputStream(targetFolder + "\\"+ sourceLocation.getName(), true);
            System.out.println("Destination Path ::"+targetFolder + "\\"+ sourceLocation.getName());            
            // Copy the bits from instream to outstream
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            in.close();
            out.close();
            noOfFiles++;
        }
    }

    public static void main(String[] args) throws IOException {

        File srcFolder = new File("C:\\sourceLocation\\");
        String destFolder = new String("C:\\targetLocation\\");
        CopyFiles cf = new CopyFiles();
        cf.copyDirectory(srcFolder, destFolder);
        System.out.println("No Of Files got Retrieved from Source ::"+cf.noOfFiles);
        System.out.println("Successfully Retrieved");
    }
}

0

如果您不想使用外部库,而是想使用java.io而不是java.nio类,您可以使用这种简洁的方法来复制文件夹及其所有内容:

/**
 * Copies a folder and all its content to another folder. Do not include file separator at the end path of the folder destination.
 * @param folderToCopy The folder and it's content that will be copied
 * @param folderDestination The folder destination
 */
public static void copyFolder(File folderToCopy, File folderDestination) {
    if(!folderDestination.isDirectory() || !folderToCopy.isDirectory())
        throw new IllegalArgumentException("The folderToCopy and folderDestination must be directories");

    folderDestination.mkdirs();

    for(File fileToCopy : folderToCopy.listFiles()) {
        File copiedFile = new File(folderDestination + File.separator + fileToCopy.getName());

        try (FileInputStream fis = new FileInputStream(fileToCopy);
             FileOutputStream fos = new FileOutputStream(copiedFile)) {

            int read;
            byte[] buffer = new byte[512];

            while ((read = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, read);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}

0

我提供了一种替代方案,无需使用第三方工具,如apache FileUtils。这可以通过命令行完成。

我在Windows上测试过,对我有效。下面是Linux的解决方案。

在这里,我利用Windows xcopy 命令来复制包括子目录在内的所有文件。我传递的参数如下所定义。

  • /e - 复制所有子目录,即使它们为空。
  • /i - 如果源是目录或包含通配符,并且目标不存在,则 xcopy 假定目标指定一个目录名称并创建一个新目录。然后,xcopy 将所有指定的文件复制到新目录中。
  • /h - 复制带有隐藏和系统文件属性的文件。默认情况下,xcopy 不会复制隐藏或系统文件

我的示例利用 ProcessBuilder 类构建进程来执行复制(xcopy & cp)命令。

Windows:

String src = "C:\\srcDir";
String dest = "C:\\destDir";
List<String> cmd = Arrays.asList("xcopy", src, dest, "/e", "/i", "/h");
try {
    Process proc = new ProcessBuilder(cmd).start();
    BufferedReader inp = new BufferedReader(new InputStreamReader(proc.getInputStream()));
    String line = null;
    while ((line = inp.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}

Linux:

String src = "srcDir/";
String dest = "~/destDir/";
List<String> cmd = Arrays.asList("/bin/bash", "-c", "cp", "r", src, dest);
try {
    Process proc = new ProcessBuilder(cmd).start();
    BufferedReader inp = new BufferedReader(new InputStreamReader(proc.getInputStream()));
    String line = null;
    while ((line = inp.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}

或者是一个可以在WindowsLinux环境下工作的组合

private static final String OS = System.getProperty("os.name");
private static String src = null;
private static String dest = null;
private static List<String> cmd = null;

public static void main(String[] args) {
    if (OS.toLowerCase().contains("windows")) { // setup WINDOWS environment
        src = "C:\\srcDir";
        dest = "C:\\destDir";
        cmd = Arrays.asList("xcopy", src, dest, "/e", "/i", "/h");

        System.out.println("on: " + OS);
    } else if (OS.toLowerCase().contains("linux")){ // setup LINUX environment
        src = "srcDir/";
        dest = "~/destDir/";
        cmd = Arrays.asList("/bin/bash", "-c", "cp", "r", src, dest);

        System.out.println("on: " + OS);
    }

    try {
        Process proc = new ProcessBuilder(cmd).start();
        BufferedReader inp = new BufferedReader(new InputStreamReader(proc.getInputStream()));
        String line = null;
        while ((line = inp.readLine()) != null) {
            System.out.println(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

}

-4

你需要使用renameTo() - 这不是很明显,我知道...但它是Java中move的等效操作...


1
但这样做不会移动文件而不是复制文件吗? - Joey
我在for循环中写了review.renameTo(trDir);,但是它没有起作用:(。目录trDir已经被创建,但是为空的。我使用的方式是正确的,不是吗? - user42155
文件没有任何反应 - 它们既没有被移动也没有被复制。 - user42155
实际上,在我的情况下,移动文件比复制文件更好。 - user42155
3
renameTo() 方法需要一个代表文件本身在其新目录下的 File 对象作为参数,而不是代表目录本身的对象。 - Michael Borgwardt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接