Ich folgte dem Tutorial Watching a Directory für Änderungen Java7 nio2, um den gesamten Inhalt eines Verzeichnisses mit dem Codebeispiel WatchDir.java rekursiv zu überwachen.Java 7 WatchService - Der Prozess kann nicht auf die Datei zugreifen, weil sie von einem anderen Prozess verwendet wird
Der Code sieht wie folgt aus:
// Get list of events for the watch key.
for (WatchEvent<?> event : key.pollEvents()) {
// This key is registered only for ENTRY_CREATE events, but an OVERFLOW event
// can occur regardless if events are lost or discarded.
if (event.kind() == OVERFLOW) {
continue;
}
// Context for directory entry event is the file name of entry.
@SuppressWarnings("unchecked")
WatchEvent<Path> ev = (WatchEvent<Path>)event;
Path fileName = ev.context();
Path fullPath = dir.resolve(fileName);
try {
// Print out event.
System.out.print("Processing file: " + fileName);
processed = fileProcessor.processFile(fullPath);
System.out.println("Processed = " + processed);
if (processed) {
// Print out event.
System.out.println(" - Done!");
}
}
catch (FileNotFoundException e) {
System.err.println("Error message: " + e.getMessage());
}
catch (IOException e) {
System.err.println("Error processing file: " + fileName.toString());
System.err.println("Error message: " + e.getMessage());
}
Ok, so dass das Problem (wo ich bin sicher, etwas Dummes zu tun) ist hier:
processed = fileProcessor.processFile(fullPath);
Und was es tut, ist so etwas wie dieses:
public synchronized boolean processFile(Path fullPath) throws IOException {
String line;
String[] tokens;
String fileName = fullPath.getFileName().toString();
String fullPathFileName = fullPath.toString();
// Create the file.
File sourceFile = new File(fullPath.toString());
// If the file does not exist, print out an error message and return.
if (sourceFile.exists() == false) {
System.err.println("ERROR: " + fullPathFileName + ": No such file");
return false;
}
// Check file extension.
if (!getFileExtension(fullPathFileName).equalsIgnoreCase("dat")) {
System.out.println(" - Ignored.");
return false;
}
// Process source file.
try (BufferedReader bReader = new BufferedReader(new FileReader(sourceFile))) {
int type;
// Process each line of the file.
while (bReader.ready()) {
// Get a single line.
line = bReader.readLine();
// Get line tokens.
tokens = line.split(delimiter);
// Get type.
type = Integer.parseInt(tokens[0]);
switch (type) {
// Type 1 = Salesman.
case 1:
-> Call static method to process tokes.
break;
// Type 2 = Customer.
case 2:
-> Call static method to process tokes.
break;
// Type 3 = Sales.
case 3:
-> Call static method to process tokes.
break;
// Other types are unknown!
default:
System.err.println("Unknown type: " + type);
break;
}
}
PrintStream ps = null;
try {
// Write output file.
// Doesn't matter.
}
finally {
if (ps != null) {
ps.close();
}
}
return true;
}
}
Das erste Mal, wenn ich ein Ereignis behandle, funktioniert alles gut! Auch wenn mehr als 1 Datei zu verarbeiten ist. Aber in den aufeinander folgenden Zeiten, ich diese Fehlermeldung:
Der Prozess kann nicht auf die Datei zugreifen kann, weil sie von einem anderen Prozess verwendet wird
Was mache ich hier falsch? Was kann ich tun, um die aufeinanderfolgenden Dateien mit Erfolg zu verarbeiten?
Zwei wichtige Hinweise, die ich vergessen zu erwähnen:
- Ich verwende Windows 7.
- Wenn ich die Anwendung im Debug-Modus laufen, es funktioniert.
EDIT: Wenn ich einen Schlaf hinzufügen, bevor ich versuche, die Datei zu verwenden, funktioniert es:
Thread.sleep(500);
// Process source file.
try (BufferedReader bReader = new BufferedReader(new FileReader(sourceFile))) {
So ist es möglich, Windows zu sein, die nicht auf die Dateien in der Zeit Entriegeln? Wie kann ich das (richtig) beheben?
es geht um :) –
Nice Trick! Es hat mir geholfen! –