O que acontece quando você lê um arquivo enquanto ele é substituído?

Respostas:

19

Isso depende do que o escritor faz.

Se o gravador substituir o arquivo existente, o leitor verá o novo conteúdo quando o gravador ultrapassar o leitor, se for o caso. Se o escritor e o leitor prosseguirem em velocidades variáveis, o leitor poderá ver alternativamente o conteúdo antigo e o novo.

Se o gravador truncar o arquivo antes de começar a gravar, o leitor será executado no final do arquivo nesse momento.

Se o gravador criar um novo arquivo e depois mover o novo arquivo para o nome antigo, o leitor continuará lendo o arquivo antigo. Se um arquivo aberto for movido ou removido, os processos que abriram o arquivo continuarão lendo esse mesmo arquivo. Se o arquivo for removido, ele realmente permanecerá no disco (mas não será possível abri-lo novamente) até que o último processo o feche.

Os sistemas Unix tendem a não ter bloqueios obrigatórios . Se um aplicativo deseja garantir que seu componente gravador e seu componente leitor não pisem nos dedos um do outro, cabe ao desenvolvedor usar o bloqueio adequado. Existem algumas exceções em que um arquivo aberto pelo kernel pode ser protegido contra gravação por aplicativos do usuário, por exemplo, uma imagem de sistema de arquivos montada em loop ou um executável que está sendo executado em algumas variantes do unix.

Gilles 'SO- parar de ser mau'
fonte
Gilles, sua explicação também se aplica a ftp/ sftpcenários? Digamos que um processo comece a ler um ftparquivo transmitido enquanto outra versão do mesmo arquivo o substitui devido a uma nova transmissão.
Iruvar
@ 1_CR Sim. Nesse caso, o escritor e o leitor são os processos do ftpd.
Gilles 'SO- stop be evil'
qual o significado de ultrapassagem aqui?
Victor Choy 10/10
@VictorChoy Significado padrão: começar por trás / depois de outra pessoa e, em algum momento, avançar à frente dela.
Gilles 'SO- stop be evil'
18

É uma condição clássica de corrida, portanto o resultado é imprevisível por definição.

Entre outros, depende de

  • fopen(3)ou open(2)modos de gravação,
  • como / se o gravador está armazenando sua saída em buffer,
  • como o leitor está lendo o arquivo,
  • a diferença de velocidade entre o leitor e o escritor,
  • a diferença horária entre o início da leitura e o escritor.
  • E, é claro, nas modernas máquinas com vários núcleos, as coisas são complicadas ainda mais por outros fatores mais baixos (por exemplo, programação de processos).

Se você precisar ler um arquivo enquanto ele estiver sendo reescrito, poderá fazer com que o gravador faça uma cópia temporária do arquivo, modifique-o e copie-o novamente para o arquivo original. É assim que se rsyncfaz, por exemplo. Existem várias maneiras de implementar isso, mas não há almoço grátis. Cada método tem suas próprias deficiências e repercussões.

Alexios
fonte
11
Essa resposta é muito mais abrangente que a minha. Excluindo minha resposta.
killermist
0

Os respondentes anteriores têm explicações mais abrangentes do que isso, mas aqui está um truque que definitivamente também funciona, praticamente fazendo exatamente o que ele deseja:

$ tail -f <filename>

Irá mostrar o final do arquivo enquanto ele está sendo gravado. Prático, se você deseja canalizar o STDERR para um arquivo, mas ainda o vê em outra janela do terminal, por exemplo.

Willoughby Will
fonte