如何在 java 中复制大于 4.3 GB 的文件
How copy files bigger than 4.3 GB in java
我正在编写一个程序部分,只是为了将文件从源文件复制到目标文件。该代码可以正常工作,但如果有一个大文件,则在目标文件达到 4.3 GB 的大小后,复制过程将结束,但有一个例外。例外是 "file is to large" 它看起来像:
java.io.IOException: Die Datei ist zu groß
at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
at sun.nio.ch.FileDispatcherImpl.write(FileDispatcherImpl.java:60)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
at sun.nio.ch.IOUtil.write(IOUtil.java:65)
at sun.nio.ch.FileChannelImpl.write(FileChannelImpl.java:211)
at java.nio.channels.Channels.writeFullyImpl(Channels.java:78)
at java.nio.channels.Channels.writeFully(Channels.java:101)
at java.nio.channels.Channels.access[=11=]0(Channels.java:61)
at java.nio.channels.Channels.write(Channels.java:174)
at java.nio.file.Files.copy(Files.java:2909)
at java.nio.file.Files.copy(Files.java:3069)
at sample.Controller.copyStream(Controller.java:318)
制作方法如下:
private void copyStream(File src, File dest){
try {
FileInputStream fis = new FileInputStream(src);
OutputStream newFos = java.nio.file.Files.newOutputStream(dest.toPath(),StandardOpenOption.WRITE);
Files.copy(src.toPath(),newFos);
newFos.flush();
newFos.close();
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
我也试过用java.io Fileoutputstream 以千字节的方式写入,但还是一样。如何复制或创建大于 4.3 GB 的文件?除了 java 以外的其他语言可能吗?这个程序我 运行 Linux (Ubuntu LTS 16.04).
提前致谢。
编辑:
非常感谢大家的帮助。正如您所说,文件系统是问题所在。在我将文件系统格式化为 exfat 后,它工作正常。
POSIX(以及 Unix)系统允许在路径上施加最大长度(你从 File.getPath()
或路径的组成部分(最后一个你可以得到使用 File.getName()
)。您可能会遇到此问题,因为文件的名称很长。
在那种情况下,文件 open
operating system call will fail with an ENAMETOOLONG
error code.
但是,消息 "File too large" 通常与“EFBIG”错误代码相关联。这更有可能是由 write
系统调用引起的:
An attempt was made to write a file that exceeds the implementation-dependent maximum file size or the process' file size limit.
可能正在打开文件进行追加,文件末尾隐含的 lseek 给出了 EFBIG
错误。
最后,如果它必须对您的内存进行某些操作,您可以尝试其他复制方法。
另一种可能是磁盘已满。
复制文件基本上有四种方式[事实证明流是基本级别上最快的]:
随流复制:
private static void copyFileUsingStream(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 {
is.close();
os.close();
}
}
复制 Java NIO classes:
private static void copyFileUsingChannel(File source, File dest) throws IOException {
FileChannel sourceChannel = null;
FileChannel destChannel = null;
try {
sourceChannel = new FileInputStream(source).getChannel();
destChannel = new FileOutputStream(dest).getChannel();
destChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
}finally{
sourceChannel.close();
destChannel.close();
}
}
使用 Apache Commons IO FileUtils 复制:
private static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException {
FileUtils.copyFile(source, dest);
}
和您的方法,使用 Java 7 和文件 class:
private static void copyFileUsingJava7Files(File source, File dest) throws IOException {
Files.copy(source.toPath(), dest.toPath());
}
编辑 1:
正如评论中所建议的,这里有三个 SO 问题,它们涵盖了问题并更好地解释了四种不同的复制方法:
- Standard concise way to copy a file in Java?
感谢@jww 指出
我正在编写一个程序部分,只是为了将文件从源文件复制到目标文件。该代码可以正常工作,但如果有一个大文件,则在目标文件达到 4.3 GB 的大小后,复制过程将结束,但有一个例外。例外是 "file is to large" 它看起来像:
java.io.IOException: Die Datei ist zu groß
at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
at sun.nio.ch.FileDispatcherImpl.write(FileDispatcherImpl.java:60)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
at sun.nio.ch.IOUtil.write(IOUtil.java:65)
at sun.nio.ch.FileChannelImpl.write(FileChannelImpl.java:211)
at java.nio.channels.Channels.writeFullyImpl(Channels.java:78)
at java.nio.channels.Channels.writeFully(Channels.java:101)
at java.nio.channels.Channels.access[=11=]0(Channels.java:61)
at java.nio.channels.Channels.write(Channels.java:174)
at java.nio.file.Files.copy(Files.java:2909)
at java.nio.file.Files.copy(Files.java:3069)
at sample.Controller.copyStream(Controller.java:318)
制作方法如下:
private void copyStream(File src, File dest){
try {
FileInputStream fis = new FileInputStream(src);
OutputStream newFos = java.nio.file.Files.newOutputStream(dest.toPath(),StandardOpenOption.WRITE);
Files.copy(src.toPath(),newFos);
newFos.flush();
newFos.close();
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
我也试过用java.io Fileoutputstream 以千字节的方式写入,但还是一样。如何复制或创建大于 4.3 GB 的文件?除了 java 以外的其他语言可能吗?这个程序我 运行 Linux (Ubuntu LTS 16.04).
提前致谢。
编辑:
非常感谢大家的帮助。正如您所说,文件系统是问题所在。在我将文件系统格式化为 exfat 后,它工作正常。
POSIX(以及 Unix)系统允许在路径上施加最大长度(你从 File.getPath()
或路径的组成部分(最后一个你可以得到使用 File.getName()
)。您可能会遇到此问题,因为文件的名称很长。
在那种情况下,文件 open
operating system call will fail with an ENAMETOOLONG
error code.
但是,消息 "File too large" 通常与“EFBIG”错误代码相关联。这更有可能是由 write
系统调用引起的:
An attempt was made to write a file that exceeds the implementation-dependent maximum file size or the process' file size limit.
可能正在打开文件进行追加,文件末尾隐含的 lseek 给出了 EFBIG
错误。
最后,如果它必须对您的内存进行某些操作,您可以尝试其他复制方法。
另一种可能是磁盘已满。
复制文件基本上有四种方式[事实证明流是基本级别上最快的]:
随流复制:
private static void copyFileUsingStream(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 {
is.close();
os.close();
}
}
复制 Java NIO classes:
private static void copyFileUsingChannel(File source, File dest) throws IOException {
FileChannel sourceChannel = null;
FileChannel destChannel = null;
try {
sourceChannel = new FileInputStream(source).getChannel();
destChannel = new FileOutputStream(dest).getChannel();
destChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
}finally{
sourceChannel.close();
destChannel.close();
}
}
使用 Apache Commons IO FileUtils 复制:
private static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException {
FileUtils.copyFile(source, dest);
}
和您的方法,使用 Java 7 和文件 class:
private static void copyFileUsingJava7Files(File source, File dest) throws IOException {
Files.copy(source.toPath(), dest.toPath());
}
编辑 1: 正如评论中所建议的,这里有三个 SO 问题,它们涵盖了问题并更好地解释了四种不同的复制方法:
- Standard concise way to copy a file in Java?
感谢@jww 指出