【发布时间】:2008-10-28 23:26:31
【问题描述】:
有没有一种高效的方法可以在 Java 中创建具有给定大小的文件?
在 C 语言中,它可以通过 ftruncate 完成(参见 that answer)。
大多数人只会将 n 个虚拟字节写入文件,但必须有更快的方法。我在想ftruncate 和Sparse files...
【问题讨论】:
有没有一种高效的方法可以在 Java 中创建具有给定大小的文件?
在 C 语言中,它可以通过 ftruncate 完成(参见 that answer)。
大多数人只会将 n 个虚拟字节写入文件,但必须有更快的方法。我在想ftruncate 和Sparse files...
【问题讨论】:
创建一个新的RandomAccessFile 并调用 setLength 方法,指定所需的文件长度。底层 JRE 实现应使用您的环境中可用的最有效方法。
下面的程序
import java.io.*;
class Test {
public static void main(String args[]) throws Exception {
RandomAccessFile f = new RandomAccessFile("t", "rw");
f.setLength(1024 * 1024 * 1024);
}
}
在 Linux 机器上将使用 ftruncate(2) 分配空间
6070 open("t", O_RDWR|O_CREAT, 0666) = 4
6070 fstat(4, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
6070 lseek(4, 0, SEEK_CUR) = 0
6070 ftruncate(4, 1073741824) = 0
在 Solaris 机器上,它将使用 fcntl(2) 系统调用的 F_FREESP64 函数。
/2: open64("t", O_RDWR|O_CREAT, 0666) = 14
/2: fstat64(14, 0xFE4FF810) = 0
/2: llseek(14, 0, SEEK_CUR) = 0
/2: fcntl(14, F_FREESP64, 0xFE4FF998) = 0
在这两种情况下,这都会导致创建一个稀疏文件。
【讨论】:
从 Java 8 开始,此方法适用于 Linux 和 Windows:
final ByteBuffer buf = ByteBuffer.allocate(4).putInt(2);
buf.rewind();
final OpenOption[] options = { StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW , StandardOpenOption.SPARSE };
final Path hugeFile = Paths.get("hugefile.txt");
try (final SeekableByteChannel channel = Files.newByteChannel(hugeFile, options);) {
channel.position(HUGE_FILE_SIZE);
channel.write(buf);
}
【讨论】:
您可以打开文件进行写入,寻找偏移量 (n-1),然后写入单个字节。操作系统会自动将文件扩展到所需的字节数。
【讨论】: