Pergunta

Eu tenho um aplicativo Java que monitora uma pasta para arquivos XML de entrada. Quando um novo arquivo é detectado eu preciso testar o arquivo que não está sendo atualizado e está fechado. Meu pensamento é usar Arquivo. canWrite () para testar esta. Existe algum problema com isso? Será esta uma boa forma de teste que um arquivo foi completamente escrito?

Outras idéias que eu estou jogando ao redor são:

  • Analise o arquivo XML de entrada e de teste que a marca de fechamento está lá.
  • Verifique se o caractere EOF.

Eu apenas não estou certo de que qualquer um destes métodos irá lidar com todos os cenários.

Foi útil?

Solução

Não, canWrite não é adequado para esta finalidade. Em geral, o arquivo será gravável mesmo se outro processo é escrita.

Você precisa de um protocolo de nível superior para coordenar o bloqueio. Se você pretende usar este código em uma única plataforma, você pode ser capaz de usar o NIO FileLock instalação . Mas ler a documentação com cuidado, e nota que em muitas plataformas, o bloqueio é apenas consultivo.

Outra abordagem é ter um processo de gravação o arquivo com um nome que o seu processo não irá reconhecer, em seguida, renomeie o arquivo para um nome reconhecível quando a gravação está completa. Na maioria das plataformas, a operação de renomeação é atômica se a origem e destino são o mesmo volume sistema de arquivos. A mudança de nome pode usar uma extensão de arquivo diferente, ou até mesmo mover o arquivo de um diretório para outro (no mesmo volume).

Uma vez que, neste caso, você está trabalhando exclusivamente com XML, procurando uma tag perto iria funcionar, mas não é infalível-o que se não houver comentários após a marcação final, ou o escritor ou simplesmente não escrever XML válido ?

Olhando para o EOF irá não trabalho. Haverá sempre um EOF, mesmo quando o escritor acaba de abrir o arquivo e ainda não escreveu nada ainda. Se assim não fosse, a coisa mais fácil seria a de permitir que o leitor comece a analisar assim que o arquivo apareceu; seria simplesmente bloquear até que o escritor fechou o arquivo. Mas o sistema de arquivos não funciona desta forma. Cada arquivo tem um fim, mesmo se algum processo está atualmente movendo-o.

Outras dicas

Além disso, se você fizer uma verificação seguido por uma gravação, então você tem uma condição de corrida. O estado pode mudar entre o cheque e a escrita. Às vezes é melhor tentar e fazer a coisa que você quer e erros identificador graciosamente. talvez um mecanismo de repetição n-tentativa com um aumento do tempo de atraso de recuo.

Ou redefinir o seu teste. Neste caso, talvez pudesse testar se o tamanho do arquivo não mudou ao longo de um período de tempo antes de processá-lo.

Outra opção é dividir o código em dois, você poderia ter outro segmento - talvez uma tarefa de quartzo - responsável por mover arquivos acabados em um diretório diferente que seus principais processos de código

.

Uma coisa que parece funcionar no Windows é este - Criar um objeto File () que representa o arquivo em questão (usando construtor com nome completo) - Criar um segundo objeto de arquivo idênticos, mesma maneira. - Tente firstFile.renameTo (secondFile)

Este manequim renomeando exercício parece suceder com arquivos que não estão abertas para edição por outro aplicativo (I testado com Word), mas não consegue se eles estão abertos.

E, como o nome do arquivo nw = o antigo nome de arquivo que não cria qualquer outro trabalho.

Tanto quanto eu sei, não há nenhuma maneira de saber se um outro processo atualmente tem um identificador aberto para um arquivo de Java. Uma opção é usar o FileLock classe de novo io. Isto não é suportado em todas as plataformas, mas se os arquivos são locais e o processo de escrever as coopera de ficheiros, esta deve funcionar para qualquer plataforma que suporte fechaduras.

Se você controlar tanto o leitor e escritor, em seguida, uma técnica de bloqueio potencial seria a criação de um bloqueio diretório - que normalmente é uma operação atômica - para a leitura e a duração processo de gravação. Se você tomar este tipo de abordagem, você tem que gerir a falha potencial de um processo resultando em um "enforcamento" diretório de bloqueio.

Como Cheekysoft mencionado, os arquivos não são atômicas e estão mal adequado para o bloqueio.

Se você não controlar o escritor - por exemplo, se ele está sendo produzido por um daemon FTP - em seguida, a técnica de mudança de nome ou atraso para a técnica de intervalo de tempo são suas melhores opções

.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top