Создать файл с заданным размером в Java
Есть ли эффективный способ создать файл с заданным размером в Java?
В C это можно сделать с помощью ftruncate (см. Ответ).
Большинство людей просто записывают в файл n фиктивных байтов, но должен быть более быстрый путь. Я думаю о ftruncate, а также о разреженных файлах...
2 ответа
Создайте новый 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 он будет использовать функцию F_FREESP64 системного вызова fcntl(2).
/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) и записать один байт. ОС автоматически расширит файл до желаемого количества байтов.