Read file when directory exists

1

I am building an application that reads a file in a certain directory, however this file will be generated in this directory at different times from another application, after the application consumes and processes the data the file is deleted, only I do not know how I can get my application to process when this file arrives in the directory.

    
asked by anonymous 10.12.2015 / 23:24

1 answer

4

I've set up an example based on the WatchingService API >.

The comments in the code explain what each command does and should give a good idea of how to process the files within a scenario similar to the one described in the question.

The code:

//define pasta a ser observada
Path pastaOrigem = Files.createDirectories(Paths.get("origem"));
//define pasta onde os arquivos sendo processados serão movidos
Path pastaProcessando = Files.createDirectories(pastaOrigem.resolve("processando"));
//define pasta onde os arquivos já processados serão movidos
Path pastaProcessados = Files.createDirectories(pastaOrigem.resolve("processados"));

//monitor da pasta
WatchService watcher = FileSystems.getDefault().newWatchService();

//registra para receber eventos de criação de arquivos no diretório
pastaOrigem.register(watcher, ENTRY_CREATE);

//loop infinito
while (true) {

    WatchKey wk = null;
    try {
        //aguarda algum evento ocorrer
        System.out.printf("Aguardando arquivos em %s", pastaOrigem);
        wk = watcher.take();
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }

    //percorre eventos recebidos
    for (WatchEvent<?> event : wk.pollEvents()) {

        //ignora se ocorreu um problema
        if (event.kind() == OVERFLOW) continue;

        //pega nome do arquivo criado
        WatchEvent<Path> ev = (WatchEvent<Path>) event;
        Path nomeArquivo = ev.context();
        Path arquivoOrigem = pastaOrigem.resolve(nomeArquivo);
        System.out.printf("Arquivo criado: %s\n", arquivoOrigem);


        //move arquivo para "processando"
        Path arquivoProcessando = pastaProcessando.resolve(nomeArquivo);
        System.out.printf("Movendo para: %s\n", arquivoProcessando);
        Files.move(arquivoOrigem, arquivoProcessando);

        //processa arquivo
        System.out.printf("Processando arquivo %s\n", arquivoProcessando);

        //move para "processados"
        Path arquivoProcessado = pastaProcessados.resolve(nomeArquivo);
        System.out.printf("Movendo para: %s\n", arquivoProcessado);
        Files.move(arquivoProcessando, arquivoProcessado);

    }

    //prepara o próximo evento ou sai caso algum erro ocorra, como o diretório não existir mais
    if (!wk.reset()) {
        break;
    }
}

//encerramento manual, caso neccesário
//watcher.close();

There are two things to consider not directly related to this API:

  • In the example above, the files created in the monitored directory are then moved to a processando and processados directory. This is done to reduce problems where the same file can be read more than once, for example. Also, if an error occurs during file processing, it can be moved to a erro folder so that you can then analyze what has occurred. This is just a hint on how to handle the read flow of the file and avoid leaving everything in one folder, which can cause many problems.

  • One point to consider is Do not generate files directly in the watched directory . If the system that generates the file does this, the file can be read at creation time, before the system completes writing to the end. So ideally you should put a file in a temporary directory and then move the file to the monitored directory after it is fully completed or transferred. Preferably, have some mechanism to validate whether the read file is consistent and avoid surprises (such as half-way imports).

  • 11.12.2015 / 03:17