Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.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_File_Copy - Fatal编程技术网

用Java复制文件的标准简明方法?

用Java复制文件的标准简明方法?,java,file,copy,Java,File,Copy,在Java中复制文件的唯一方法是打开流、声明缓冲区、读入一个文件、在其中循环并将其写入另一个steam,这一直困扰着我。web上充斥着类似的、但仍然略有不同的此类解决方案的实现 有没有更好的方法保持在Java语言的范围内(意思是不涉及执行特定于操作系统的命令)?也许在某个可靠的开源实用程序包中,这至少会掩盖这个底层实现,并提供一个单线解决方案?正如工具包上面提到的,Apache Commons IO是一条路要走。;它为你处理所有的重物 作为后记,请注意FileUtils的最新版本(如2.0.1版

在Java中复制文件的唯一方法是打开流、声明缓冲区、读入一个文件、在其中循环并将其写入另一个steam,这一直困扰着我。web上充斥着类似的、但仍然略有不同的此类解决方案的实现


有没有更好的方法保持在Java语言的范围内(意思是不涉及执行特定于操作系统的命令)?也许在某个可靠的开源实用程序包中,这至少会掩盖这个底层实现,并提供一个单线解决方案?

正如工具包上面提到的,Apache Commons IO是一条路要走。;它为你处理所有的重物


作为后记,请注意FileUtils的最新版本(如2.0.1版)添加了NIO用于复制文件的功能,这在很大程度上是因为NIO例程延迟了直接复制到OS/文件系统,而不是通过Java层读写字节来处理它。因此,如果您正在寻找性能,那么可能需要检查您是否正在使用最新版本的FileUtils。

我会避免使用类似ApacheCommons的大型api。这是一个过于简单的操作,它内置于新NIO包中的JDK中。在前面的回答中,它已经被链接到了,但是NIOAPI中的关键方法是新函数“transferTo”和“transferFrom”

其中一篇链接文章介绍了如何使用transferFrom将此函数集成到代码中的一个好方法:

public static void copyFile(File sourceFile, File destFile) throws IOException {
    if(!destFile.exists()) {
        destFile.createNewFile();
    }

    FileChannel source = null;
    FileChannel destination = null;

    try {
        source = new FileInputStream(sourceFile).getChannel();
        destination = new FileOutputStream(destFile).getChannel();
        destination.transferFrom(source, 0, source.size());
    }
    finally {
        if(source != null) {
            source.close();
        }
        if(destination != null) {
            destination.close();
        }
    }
}

学习NIO可能有点棘手,所以您可能希望在开始学习NIO之前,相信这个机制。从个人经验来看,如果您没有相关经验,并且是通过java.IO流引入IO的,那么要了解这一点可能非常困难。

请注意,所有这些机制都只复制文件的内容,而不复制权限等元数据。因此,如果要在linux上复制或移动一个可执行的.sh文件,那么新文件将不会是可执行的

为了真正复制或移动文件,即获得与从命令行复制相同的结果,实际上需要使用本机工具。shell脚本或JNI


显然,这可能在Java7-中得到修复。祝你好运

在Java 7中作为标准提供,path.copyTo:


我不敢相信他们花了这么长时间才将文件复制这样普通而简单的东西标准化:(

谷歌的番石榴图书馆也有一个:

公共静态无效副本(从, (至) 投掷 将所有字节从一个文件复制到另一个文件

警告:如果
to
表示现有文件,则该文件 将被从到的
内容覆盖。如果
引用同一文件,该文件的内容 将被删除。

参数:-源文件-目标文件

抛出: -如果发生I/O错误 -如果来自.equals(to)


现在使用Java 7,您可以使用以下try with resource语法:

public static void copy(Filefrom, Fileto) throws IOException 或者,更好的是,这也可以通过使用Java 7中引入的新文件类来实现:

public static void copyFile( File from, File to ) throws IOException {

    if ( !to.exists() ) { to.createNewFile(); }

    try (
        FileChannel in = new FileInputStream( from ).getChannel();
        FileChannel out = new FileOutputStream( to ).getChannel() ) {

        out.transferFrom( in, 0, in.size() );
    }
}

非常时髦,嗯?

上述代码可能存在三个问题:

  • 如果getChannel引发异常,则可能会泄漏开放流
  • 对于大文件,您可能试图一次传输操作系统无法处理的文件
  • 您忽略了transferFrom的返回值,因此它可能只是复制了文件的一部分

  • 这就是为什么
    org.apache.tools.ant.util.ResourceUtils.copyResource
    如此复杂的原因。还要注意,虽然transferFrom是可以的,但在Linux上的JDK 1.4上transferTo会中断(请参阅)–Jesse Glick Jan

    如果您使用的是已经使用Spring的web应用程序,并且如果您不想将Apache Commons IO用于简单的文件复制,那么您可以使用Spring框架。

    • 这些方法是经过性能设计的(它们与操作系统本机I/O集成)
    • 这些方法适用于文件、目录和链接
    • 所提供的每个选项都可以省略-它们是可选的
    实用程序类
    package com.yourcompany.nio;
    类文件{
    静态int copyRecursive(路径源、路径目标、布尔提示、CopyOptions选项…){
    CopyVisitor CopyVisitor=新的CopyVisitor(源、目标、选项).copy();
    枚举集文件访问;
    if(Arrays.toList(options).contains(java.nio.file.LinkOption.NOFOLLOW\u LINKS){
    fileVisitOpts=EnumSet.noneOf(FileVisitOption.class)
    }否则{
    fileVisitOpts=EnumSet.of(FileVisitOption.FOLLOW\u链接);
    }
    walkFileTree(源[i],fileVisitOpts,Integer.MAX_值,copyVisitor);
    }
    私有类CopyVisitor实现FileVisitor{
    最终路径源;
    最终路径目标;
    最终复制选项[]选项;
    CopyVisitor(路径源、路径目标、CopyOptions…){
    this.source=source;this.target=target;this.options=options;
    };
    @凌驾
    FileVisitResult preVisitDirectory(路径目录,基本文件属性属性属性){
    //在访问目录中的条目之前,我们复制目录
    //(如果目录已经存在,则可以)。
    Path newdir=target.resolve(source.relativize(dir));
    试一试{
    复制(dir、newdir、options);
    }捕获(FileAlreadyExistsException x){
    //忽略
    }捕获(IOX异常){
    系统错误格式(“无法创建:%s:%s%n”,newdir,x);
    返回SKIP_子树;
    }
    继续返回;
    }
    @凌驾
    公共文件VisitResult visitFile(路径文件,基本文件属性属性属性){
    Path newfile=target.resolve(source.relativize(file));
    
    public static void copyFile( File from, File to ) throws IOException {
        Files.copy( from.toPath(), to.toPath() );
    }
    
    package com.yourcompany.nio;
    
    class Files {
    
        static int copyRecursive(Path source, Path target, boolean prompt, CopyOptions options...) {
            CopyVisitor copyVisitor = new CopyVisitor(source, target, options).copy();
            EnumSet<FileVisitOption> fileVisitOpts;
            if (Arrays.toList(options).contains(java.nio.file.LinkOption.NOFOLLOW_LINKS) {
                fileVisitOpts = EnumSet.noneOf(FileVisitOption.class) 
            } else {
                fileVisitOpts = EnumSet.of(FileVisitOption.FOLLOW_LINKS);
            }
            Files.walkFileTree(source[i], fileVisitOpts, Integer.MAX_VALUE, copyVisitor);
        }
    
        private class CopyVisitor implements FileVisitor<Path>  {
            final Path source;
            final Path target;
            final CopyOptions[] options;
    
            CopyVisitor(Path source, Path target, CopyOptions options...) {
                 this.source = source;  this.target = target;  this.options = options;
            };
    
            @Override
            FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
            // before visiting entries in a directory we copy the directory
            // (okay if directory already exists).
            Path newdir = target.resolve(source.relativize(dir));
            try {
                Files.copy(dir, newdir, options);
            } catch (FileAlreadyExistsException x) {
                // ignore
            } catch (IOException x) {
                System.err.format("Unable to create: %s: %s%n", newdir, x);
                return SKIP_SUBTREE;
            }
            return CONTINUE;
        }
    
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
            Path newfile= target.resolve(source.relativize(file));
            try {
                Files.copy(file, newfile, options);
            } catch (IOException x) {
                System.err.format("Unable to copy: %s: %s%n", source, x);
            }
            return CONTINUE;
        }
    
        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
            // fix up modification time of directory when done
            if (exc == null && Arrays.toList(options).contains(COPY_ATTRIBUTES)) {
                Path newdir = target.resolve(source.relativize(dir));
                try {
                    FileTime time = Files.getLastModifiedTime(dir);
                    Files.setLastModifiedTime(newdir, time);
                } catch (IOException x) {
                    System.err.format("Unable to copy all attributes to: %s: %s%n", newdir, x);
                }
            }
            return CONTINUE;
        }
    
        @Override
        public FileVisitResult visitFileFailed(Path file, IOException exc) {
            if (exc instanceof FileSystemLoopException) {
                System.err.println("cycle detected: " + file);
            } else {
                System.err.format("Unable to copy: %s: %s%n", file, exc);
            }
            return CONTINUE;
        }
    }
    
    long bytes = java.nio.file.Files.copy( 
                     new java.io.File("<filepath1>").toPath(), 
                     new java.io.File("<filepath2>").toPath(),
                     java.nio.file.StandardCopyOption.REPLACE_EXISTING,
                     java.nio.file.StandardCopyOption.COPY_ATTRIBUTES,
                     java.nio.file.LinkOption.NOFOLLOW_LINKS);
    
    long bytes = java.nio.file.Files.move( 
                     new java.io.File("<filepath1>").toPath(), 
                     new java.io.File("<filepath2>").toPath(),
                     java.nio.file.StandardCopyOption.ATOMIC_MOVE,
                     java.nio.file.StandardCopyOption.REPLACE_EXISTING);
    
    long bytes = com.yourcompany.nio.Files.copyRecursive( 
                     new java.io.File("<filepath1>").toPath(), 
                     new java.io.File("<filepath2>").toPath(),
                     java.nio.file.StandardCopyOption.REPLACE_EXISTING,
                     java.nio.file.StandardCopyOption.COPY_ATTRIBUTES
                     java.nio.file.LinkOption.NOFOLLOW_LINKS );
    
    public void copy(File src, File dst) throws IOException {
        InputStream in = new FileInputStream(src);
        try {
            OutputStream out = new FileOutputStream(dst);
            try {
                // Transfer bytes from in to out
                byte[] buf = new byte[1024];
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
            } finally {
                out.close();
            }
        } finally {
            in.close();
        }
    }
    
    private void copy(final File f1, final File f2) throws IOException {
        f2.createNewFile();
    
        final RandomAccessFile file1 = new RandomAccessFile(f1, "r");
        final RandomAccessFile file2 = new RandomAccessFile(f2, "rw");
    
        file2.getChannel().write(file1.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, f1.length()));
    
        file1.close();
        file2.close();
    }
    
    public static void copyFile(File src, File dst) throws IOException
    {
        long p = 0, dp, size;
        FileChannel in = null, out = null;
    
        try
        {
            if (!dst.exists()) dst.createNewFile();
    
            in = new FileInputStream(src).getChannel();
            out = new FileOutputStream(dst).getChannel();
            size = in.size();
    
            while ((dp = out.transferFrom(in, p, size)) > 0)
            {
                p += dp;
            }
        }
        finally {
            try
            {
                if (out != null) out.close();
            }
            finally {
                if (in != null) in.close();
            }
        }
    }
    
    File src = new File("original.txt");
    File target = new File("copy.txt");
    
    Files.copy(src.toPath(), target.toPath(), StandardCopyOption.REPLACE_EXISTING);
    
    private static void copyFileUsingJava7Files(File source, File dest) throws IOException {
        Files.copy(source.toPath(), dest.toPath());
    }
    
    private static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException {
        FileUtils.copyFile(source, dest);
    }
    
    private static void copyFileUsingGuava(File source,File dest) throws IOException{
        Files.copy(source,dest);          
    }
    
    import java.io.Closeable;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;
    import java.text.DecimalFormat;
    
    
    public class test {
    
    private static final int BUFFER = 4096*16;
    static final DecimalFormat df = new DecimalFormat("#,###.##");
    public static void nioBufferCopy(final File source, final File target )  {
        FileChannel in = null;
        FileChannel out = null;
        double  size=0;
        long overallT1 =  System.currentTimeMillis();
    
        try {
            in = new FileInputStream(source).getChannel();
            out = new FileOutputStream(target).getChannel();
            size = in.size();
            double size2InKB = size / 1024 ;
            ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER);
    
            while (in.read(buffer) != -1) {
                buffer.flip();
    
                while(buffer.hasRemaining()){
                    out.write(buffer);
                }
    
                buffer.clear();
            }
            long overallT2 =  System.currentTimeMillis();
            System.out.println(String.format("Copied %s KB in %s millisecs", df.format(size2InKB),  (overallT2 - overallT1)));
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    
        finally {
            close(in);
            close(out);
        }
    }
    
    private static void close(Closeable closable)  {
        if (closable != null) {
            try {
                closable.close();
            } catch (IOException e) {
                if (FastCopy.debug)
                    e.printStackTrace();
            }    
        }
    }
    
    private static long fileCopyUsingFileStreams(File fileToCopy, File newFile) throws IOException {
        FileInputStream input = new FileInputStream(fileToCopy);
        FileOutputStream output = new FileOutputStream(newFile);
        byte[] buf = new byte[1024];
        int bytesRead;
        long start = System.currentTimeMillis();
        while ((bytesRead = input.read(buf)) > 0)
        {
            output.write(buf, 0, bytesRead);
        }
        long end = System.currentTimeMillis();
    
        input.close();
        output.close();
    
        return (end-start);
    }
    
    private static long fileCopyUsingNIOChannelClass(File fileToCopy, File newFile) throws IOException
    {
        FileInputStream inputStream = new FileInputStream(fileToCopy);
        FileChannel inChannel = inputStream.getChannel();
    
        FileOutputStream outputStream = new FileOutputStream(newFile);
        FileChannel outChannel = outputStream.getChannel();
    
        long start = System.currentTimeMillis();
        inChannel.transferTo(0, fileToCopy.length(), outChannel);
        long end = System.currentTimeMillis();
    
        inputStream.close();
        outputStream.close();
    
        return (end-start);
    }
    
    private static long fileCopyUsingApacheCommons(File fileToCopy, File newFile) throws IOException
    {
        long start = System.currentTimeMillis();
        FileUtils.copyFile(fileToCopy, newFile);
        long end = System.currentTimeMillis();
        return (end-start);
    }
    
    private static long fileCopyUsingNIOFilesClass(File fileToCopy, File newFile) throws IOException
    {
        Path source = Paths.get(fileToCopy.getPath());
        Path destination = Paths.get(newFile.getPath());
        long start = System.currentTimeMillis();
        Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
        long end = System.currentTimeMillis();
    
        return (end-start);
    }