4

我想将大文件从本地机器复制到 Samba-Server(在同一个 GBit-LAN​​ 中)。当使用我的本地文件管理器(Ubuntu 上的 Nemo)时,文件以 ~45 MB/s 的速度复制。但是当使用 Java 时,速度总是低于 8 MB/s。

这是我使用 Java 的首选 Files.copy 方法的示例代码:

public static void main(String[] args) throws IOException {
    Path src = Paths.get(args[0]);
    Path dst = Paths.get(args[1]);
    System.out.println("Copy   " + src);
    System.out.println("To     " + dst);

    long start = System.currentTimeMillis();
    Files.copy(src, dst);
    long end = System.currentTimeMillis();

    double took = end - start;
    took /= 1000;
    System.out.println("Speed: " + getReadableSpeed(((double) src.toFile().length()) / took, 2) + "\n");
}

这是输出:

Local To Local
Copy   /media/files/bigfile.avi
To     /media/files/bigfile.avi.bak
Speed: 68 MB/s

Local To NAS
Copy   /media/files/bigfile.avi
To     /home/biggie/.gvfs/nas/backup/bigfile.avi
Speed: 7,7 MB/s

将文件从本地计算机复制回本地计算机时,速度很好。但是,当目标是 NAS 时,速度会急剧下降(同时使用 OpenJDK 7 和 Oracles JDK 7)。

在 Windows 上,我的速度更快:

Local To NAS
Copy   Z:\files\bigfile.avi
To     Y:\backup\bigfile.avi
Speed: 37 MB/s

你知道为什么使用 Java 在 Linux 上传输文件很慢吗?或者更好:您对此有解决方案吗?:-)

一种解决方法可能是从 Java 调用本机“cp”或“rsync --progress”。但我更喜欢纯 Java 的方式:-)

PS:通过从 FileInputStream 读取并写入 FileOutputStream 来手动复制也很慢(< 8MB/s)。;-)

4

1 回答 1

1

Java 将通过常规文件系统挂载访问 SMB 共享。Nemo 可能通过更快/更好调整的不同机制访问 SMB 共享。

无论哪种方式,如果文件传输速度至关重要,您很可能会使用外部应用程序获得最佳结果。(确切地说,哪一个将是特定于操作系统的......并且超出了 StackOverflow 的范围。)


我简要了解了如何Files.copy实施。看来实际的文件复制是由本机代码方法(sun.nio.fs.UnixFileCopy.transfer(...))实现的。基于此,我认为复制大文件(通过常规文件系统挂载)的实用程序不应该Files.copy(...). 它需要以不同的方式访问它以实现显着的加速。

于 2013-06-27T16:51:31.403 回答