Normalmente, existem dois níveis de buffer envolvidos:
- Buffers internos
- Buffers do sistema operacional
Os buffers internos são buffers criados pelo tempo de execução / biblioteca / linguagem contra os quais você está programando e devem acelerar as coisas, evitando chamadas do sistema para cada gravação. Em vez disso, quando você grava em um objeto de arquivo, grava em seu buffer e sempre que o buffer é preenchido, os dados são gravados no arquivo real usando chamadas do sistema.
No entanto, devido aos buffers do sistema operacional, isso pode não significar que os dados sejam gravados no disco . Pode apenas significar que os dados são copiados dos buffers mantidos pelo seu tempo de execução nos buffers mantidos pelo sistema operacional.
Se você escrever algo e ele terminar no buffer (somente), e a energia for cortada em sua máquina, esses dados não estarão no disco quando a máquina for desligada.
Portanto, para ajudar você a ter os métodos flush
e fsync
, em seus respectivos objetos.
O primeiro flush
,, simplesmente escreverá todos os dados que permanecem em um buffer de programa no arquivo real. Normalmente, isso significa que os dados serão copiados do buffer do programa para o buffer do sistema operacional.
Especificamente, o que isso significa é que, se outro processo tiver o mesmo arquivo aberto para leitura, ele poderá acessar os dados que você acabou de liberar para o arquivo. No entanto, isso não significa necessariamente que ele foi "permanentemente" armazenado no disco.
Para fazer isso, é necessário chamar o os.fsync
método que garante que todos os buffers do sistema operacional sejam sincronizados com os dispositivos de armazenamento para os quais eles são, ou seja, esse método copiará os dados dos buffers do sistema operacional para o disco.
Normalmente, você não precisa se preocupar com nenhum dos métodos, mas se estiver em um cenário em que a paranóia sobre o que realmente acaba em disco é uma coisa boa, faça as duas chamadas conforme as instruções.
Adendo em 2018.
Observe que agora os discos com mecanismos de cache são muito mais comuns do que em 2013, então agora há ainda mais níveis de cache e buffers envolvidos. Eu assumir estes buffers serão tratadas pelas chamadas de sincronização / lave bem, mas eu realmente não sei.
with file('blah') as fd: #dostuff
construção, sei que ela garante o fechamento do descritor de arquivo. Também libera ou sincroniza?fsync
é necessário para a atomicidade. você não pode esperar fechar um arquivo, reabri-lo e encontrar seu conteúdo sem umfsync
no meio. Geralmente funciona, mas não no linux com ext4 e opções de montagem padrão, por exemplo. Tambémfsync
não é garantido que você realmente gire o ferro nos pratos, porque 1: fsync pode ser desativado (no modo laptop) e 2: o buffer interno do disco rígido pode não ser instruído a lavar.Porque o sistema operacional pode não fazer isso. A operação de liberação força os dados do arquivo para o cache de arquivos na RAM e, a partir daí, é tarefa do sistema operacional enviá-los para o disco.
fonte
actually
é relativo aqui: se o dispositivo de destino tiver o cache de gravação ativado, os dados poderão não ter atingido os pratos / chips reais quandoos.fsync()
retornarem.Ele libera o buffer interno, o que supostamente faz com que o sistema operacional grave o buffer no arquivo. [1] O Python usa o buffer padrão do sistema operacional, a menos que você o configure de outra forma.
Mas, às vezes, o sistema operacional ainda escolhe não cooperar. Especialmente com coisas maravilhosas, como atrasos de gravação no Windows / NTFS. Basicamente, o buffer interno é liberado, mas o buffer do sistema operacional ainda o mantém. Então você precisa dizer ao sistema operacional para gravá-lo em disco
os.fsync()
nesses casos.[1] http://docs.python.org/library/stdtypes.html
fonte
Basicamente, o flush () limpa seu buffer de RAM, seu poder real é que ele permite que você continue gravando posteriormente - mas não deve ser considerado o melhor / mais seguro recurso de gravação em arquivo. Está liberando sua RAM para mais dados, isso é tudo. Se você deseja garantir que os dados sejam gravados no arquivo com segurança, use close ().
fonte