Ignorar arquivos temporários ao implementar serviço de notificação da API NIO 2.0

Ola grandes mentes brilhantes e mestres da boa programação. Estou com um problema que tentei resolver aplicando meus conhecimentos mas não consegui resolver.

O meu ambiente de desenvolvimento
Windows 7 x64, Eclipse Juno 4.2, Java SE 7 update 9, API NIO 2.0.

O ambiente de testes
Windows XP SP3, Java 7 update 6.

Objetivo do sistema
Estou implementando um serviço de monitoramento e notificação de eventos que ocorrem em um dado diretório. O único evento tratado pela aplicação é de Criação/Edição de arquivos dentro do diretório configurado para o serviço.

Estou implementando a aplicação utilizando a interface WatchService. Nesta classe existe uma lógica para monitorar e notificar todo tipo de arquivo que seja criado na pasta.
Dentro os arquivos suportados, estão arquivos “.docx” criados pelo word, “.pdf”, “.rtf” criados pelo wordpad, “.txt” criados pelon notepad e qualquer outro tipo de arquivo.

O problema
O serviço notifica qualquer arquivo, de qualquer extensão, ou seja, arquivos temporários e os arquivos “fantasmas” ele também identifica. O meu problema é ignorar estes arquivos pelo meu serviço.

O código do serviço implementado abaixo, é somente o método que processo eventos:

		for (;;) {
			WatchKey key = null;

			try {
				key = watcher.take();
			} catch (InterruptedException exception) {
				exception.printStackTrace();
				return;
			}

			if (isRecognizedPath(key) == false) {
				System.err.println("WatchKey não reconhecida!!");
				continue;
			}

			Path workingPath = keys.get(key);

			for (WatchEvent<?> event : key.pollEvents()) {
				Kind<?> kind = event.kind();

				// Um tipo de evento especial que provavelmente foi perdido ou
				// descartado
				if (kind == OVERFLOW) {
					continue;
				}

				WatchEvent<Path> processedEvent = cast(event);
				Path fileName = processedEvent.context();
				Path filePath = workingPath.resolve(fileName);

				try {
					LOGGER.info(
							String.format(
									"%s >> exists=%s; directory=%s; hidden=%s; regular=%s; temporary=%s; empty=%s.",
									filePath, Files.exists(filePath),
									Files.isDirectory(filePath),
									Files.isHidden(filePath),
									Files.isRegularFile(filePath),
									FileUtilities.isTemporaryFile(filePath),
									Files.size(filePath) == 0));
					System.out.println();
				} catch (IOException e) {
					LOGGER.severe(e.getClass().toString() + "; "
							+ e.getMessage());
				}

				if (isValidPath(filePath) == false) {
					continue;
				}

				eventNotifierWindow.setTxtNotificationText(filePath);
				eventNotifierWindow.setVisible(true);

				if (eventNotifierWindow.getWindowExitCode() == EXIT_CODE.CONFIRMED) {
					SendProtocolUI sendProtocolWindow = new SendProtocolUI();
					sendProtocolWindow.setAttachedField(filePath.toString());
					sendProtocolWindow.setVisible(true);

					if (sendProtocolWindow.isSentProtocol()) {
						try {
							FileUtilities.copyFile(filePath.toFile(),
									sendProtocolWindow
									.getTextProtocolNumber().getText());
						} catch (IOException e) {
							LOGGER.severe("Attempting move a sent protocol. Error: "
									+ e.getClass().getName()
									+ ": "
									+ e.getMessage());
							JOptionPane
							.showMessageDialog(
									eventNotifierWindow,
									"Falha ao tentar COPIAR o protocolo enviado para a pasta '"
											+ SystemUtilitiesConstants.DIR_NAME_PROTOCOLS_SENT
											+ "'.",
											"Falha ao mover arquivo",
											JOptionPane.ERROR_MESSAGE);
						}

						JOptionPane.showMessageDialog(eventNotifierWindow,
								"Protocolo enviado com sucesso!!!",
								"Envio de Protocolo",
								JOptionPane.INFORMATION_MESSAGE);
					}
				} else {
					try {
						FileUtilities.copyFile(filePath.toFile(), null);
					} catch (IOException e) {
						LOGGER.severe("Attempting move a not sent protocol. Error: "
								+ e.getClass().getName()
								+ ": "
								+ e.getMessage());
						JOptionPane
						.showMessageDialog(
								eventNotifierWindow,
								"Falha ao tentar copiar o arquivo não enviado para a pasta '"
										+ SystemUtilitiesConstants.DIR_NAME_PROTOCOLS_NOT_SENT
										+ "'.",
										"Falha ao copiar arquivo",
										JOptionPane.ERROR_MESSAGE);
					}
				}
			}

			// Reseta o token e remove do conjunto se o diretório estiver
			// inacessível
			if (resetKey(key) == false) {
				break;
			}
		}

A implementação deste método

				if (isValidPath(filePath) == false) {
					continue;
				}

está descrita abaixo:

	/**
	 * Valida o arquivo processado pelo evento detectado na pasta que está sendo
	 * monitorada. A validação inclui verificações como:<br>
	 * <b>Se o arquivo existir;<br>
	 * Se o arquivo não for um diretório;<br>
	 * Se o arquivo não estiver oculto (Uma exceção poderá ser lançada caso o
	 * arquivo esteja inacessível);<br>
	 * Se o arquivo é regular;<br>
	 * Se o arquivo não é temporário.<br>
	 * Se o arquivo contém conteúdo, ou seja, se seu tamanho em bytes é maior
	 * que 0</b>.
	 * 
	 * @param path
	 *            o caminho absoluto do arquivo processado pelo evento.
	 * @return <b>true</b> se o arquivo processado pelo evento é valido.
	 */
	public boolean isValidPath(Path path) {
		boolean exists = Files.exists(path);
		if (exists == false)
			return false;
		boolean directory = Files.isDirectory(path);
		if (directory)
			return false;
		boolean hidden;
		try {
			hidden = Files.isHidden(path);
		} catch (IOException exception) {
			// impossível acessar arquivo ou ler atributos
			return false;
		}
		long size;
		try {
			size = Files.size(path);
		} catch (IOException e) {
			// impossível acessar ou ler arquivo
			return false;
		}

		return hidden == false && Files.isRegularFile(path)
				&& FileUtilities.isTemporaryFile(path) == false && size > 0;
	}

[b]Por favor, alguém poderia fazer a imensa gentileza de me indicar uma solução, alguma dica valiosa que foi testada e funcionaria ou citar alguém que teve um problema parecido com o meu e conseguiu resolver?

Este serviço está em uma aplicação de sincronização de arquivos e é de imensa urgência, pois o prazo de entrega já expirou.[/b]

Deste antemão deixo meu agradecimento, ao pessoal do fórum a seus leitores. É um fórum admirável.

Poxa, obrigado heim pessoal do forum e administradores, ninguém nem para falar que não sabem como resolver ou que não entenderam.

Caramba eu pensei que neste forum o pessoal gostava de ser colaborativo e ajudar com a comunidade, é meu primeiro post e a primeira impressão é a que fica.

Muito obrigado aí pessoal por nenhuma ajuda.

Na sua lógica você não listou os arquivos que você queria ou os arquivos que você não queria.

Do jeito que você escreveu, vem tudo mesmo.

Como a aplicação que escreve os arquivos temporários não tem a obrigação de botar um flag “temporário” no arquivo (esse flag existe no Windows, mas nunca vi ninguém usando isso em uma aplicação de verdade) então o pessoal da Oracle não implementou, no NIO, uma verificação de “flag temporário” na API.

Como eu sempre digo: se a API não tem um filtro de arquivos (você deve ter lido a documentação com atenção, não?) então você tem de escrevê-lo você mesmo.

A propósito, estou desconfiado que você tinha de entregar o tal serviço às 18:00 de sexta-feira passada, e se cadastrou aqui no fórum às 17:00 - e casualmente era feriado na cidade de São Paulo - onde 80% dos integrantes do GUJ que respondem frequentemente trabalham ou estudam. Então você teve o azar de ninguém ver seu problema nesse dia.

Mesmo que não fosse feriado, é meio complicado alguém responder a você no final de uma tarde de sexta-feira, que é o dia nacional da cerveja :slight_smile: