2016-03-12 2 views
0

В C, когда я вызываю open(), чтобы открыть файловый дескриптор, я должен явно передать флаг O_SYNC, чтобы гарантировать, что запись в этот файл будет сохранена на диск к моменту возврата write(). Если я захочу, я смогу не поставьте O_SYNC на open(), а затем мои записи вернутся намного быстрее, потому что перед возвратом они должны будут сделать это в кэш файловой системы. Если захочу, позже я могу заставить все выдающиеся записи в этот файл записывать на диск, вызывая fsync(), который блокируется до завершения этой операции. (Более подробная информация доступна обо всем этом в Linux man page.)запись файла в Java без семантики O_SYNC

Есть ли способ сделать это на Java? Самое похожее на то, что я мог найти, это использовать и называть его .flush(), но если я делаю записи в рандомизированных смещениях файлов, я считаю, что это означает, что внутренний буфер для выходного потока может в конечном итоге потреблять много памяти.

+0

Если вы делаете записи в случайные смещения, вы не можете использовать 'BufferedOutputStream' в любом случае, потому что это последовательный. Вам нужно будет использовать что-то вроде «RandomAccessFile», но тогда я не знаю, как управлять его буферизацией (если таковой вообще есть). Вы можете посмотреть на «SeekableByteChannel», созданный с помощью [Files.newByteChannel] (https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#newByteChannel-java.nio .file.Path-java.util.Set-java.nio.file.attribute.FileAttribute ...-), но я не использовал его, поэтому не могу дать подробный ответ. –

ответ

0

Основываясь на комментарии Сергея Таченова, я обнаружил, что для этого вы можете использовать FileChannel. Вот пример кода, который я думаю, что делает трюк:

import java.nio.*; 
import java.nio.channels.*; 
import java.nio.file.*; 
import java.nio.file.attribute.*; 
import java.io.*; 
import java.util.*; 
import java.util.concurrent.*; 

import static java.nio.file.StandardOpenOption.*; 

public class Main { 
    public static void main(String[] args) throws Exception { 

     // Open the file as a FileChannel. 
     Set<OpenOption> options = new HashSet<>(); 
     options.add(WRITE); 
     // options.add(SYNC);  <------- This would force O_SYNC semantics. 
     try (FileChannel channel = FileChannel.open(Paths.get("./test.txt"), options)) { 

      // Generate a bit data to write. 
      ByteBuffer buffer = ByteBuffer.allocate(4096); 
      for (int i = 0; i < 10; i++) { 
       buffer.put(i, (byte) i); 
      } 

      // Choose a random offset between 0 and 1023 and write to it. 
      long offset = ThreadLocalRandom.current().nextLong(0, 1024); 
      channel.write(buffer, offset); 
     } 
    } 
} 
1

Использование Java 7 NIO FileChannel # force метод:

RandomAccessFile aFile = new RandomAccessFile("file.txt", "rw"); 
FileChannel inChannel = aFile.getChannel(); 
// ..................... 
// flushes all unwritten data from the channel to the disk 
channel.force(true); 

Важная деталь:

Если файл не находится на локальном устройстве такая гарантия не предоставляется.

Смежные вопросы