Подтвердить что ты не робот

Создать файл с заданным размером в Java

Существует ли эффективный способ создания файла с заданным размером в Java?

В C это можно сделать с помощью ftruncate (см. этот ответ).

Большинство людей просто пишут n фиктивные байты в файл, но должен быть более быстрый путь. Я имею в виду ftruncate, а также разреженные файлы...

4b9b3361

Ответ 1

Создайте новый 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

В обоих случаях это приведет к созданию разреженного файла.

Ответ 2

Вы можете открыть файл для записи, искать смещение (n-1) и написать один байт. ОС автоматически расширит файл до требуемого количества байтов.

Ответ 3

Начиная с 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);
}