Java: Öffnen und Lesen aus einer Datei, ohne es zu Sperren
Frage
muss ich mit Java zu imitieren ‚tail -f‘ in der Lage sein. Ich versuche, eine Protokolldatei zu lesen, wie es von einem anderen Prozess geschrieben wird, aber wenn ich die Datei zum Lesen öffnen, sperrt es die Datei und der andere Prozess mehr, um es nicht schreiben kann. Jede Hilfe wäre sehr geschätzt!
Hier ist der Code, dass ich bin derzeit mit:
public void read(){
Scanner fp = null;
try{
fp = new Scanner(new FileReader(this.filename));
fp.useDelimiter("\n");
}catch(java.io.FileNotFoundException e){
System.out.println("java.io.FileNotFoundException e");
}
while(true){
if(fp.hasNext()){
this.parse(fp.next());
}
}
}
Lösung
Schwanz Wiederaufbau ist schwierig aufgrund einiger Sonderfälle wie Datei Abschneiden und (Zwischen-) Löschen. Um die Datei zu öffnen, ohne dass wie so Verwendung StandardOpenOption.READ
mit dem neuen Java-Datei-API-Sperren:
try (InputStream is = Files.newInputStream(path, StandardOpenOption.READ)) {
InputStreamReader reader = new InputStreamReader(is, fileEncoding);
BufferedReader lineReader = new BufferedReader(reader);
// Process all lines.
String line;
while ((line = lineReader.readLine()) != null) {
// Line content content is in variable line.
}
}
Für meinen Versuch, einen Schwanz in Java sehen zu erstellen:
- Method
examineFile(…)
in https: // GitHub. com / AugustusKling / Ertrag / Blob / Master / src / main / java / Ertrag / input / file / FileMonitor.java - Das oben gezeigte verwendet wird von https: // github.com/AugustusKling/yield/blob/master/src/main/java/yield/input/file/FileInput.java einen Schwanz Betrieb zu erstellen. Die
queue.feed(lineContent)
geht Linie Inhalte für von den Hörern der Verarbeitung und würde Ihrethis.parse(…)
entsprechen.
Sie können ferner Inspiration von diesem Code zu übernehmen oder kopieren Sie einfach die Teile, die Sie benötigen. Lassen Sie uns wissen, wenn Sie irgendwelche Probleme feststellen, dass ich bin mir nicht bewusst.
Andere Tipps
java.io gibt Ihnen eine obligatorische Dateisperre und java.nio gibt Ihnen ein Beratungsdateisperre
Wenn Sie eine beliebige Datei lesen möchten, ohne Sperre Sie unter Klassen verwenden können,
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
Wenn Sie an Schwanz wollen eine Datei Zeile für Zeile bei Temperaturen unter Code für die gleiche
public void tail(String logPath){
String logStr = null;
FileChannel fc = null;
try {
fc = FileChannel.open(Paths.get(logPath), StandardOpenOption.READ);
fc.position(fc.size());
} catch (FileNotFoundException e1) {
System.out.println("FileNotFoundException occurred in Thread : " + Thread.currentThread().getName());
return;
} catch (IOException e) {
System.out.println("IOException occurred while opening FileChannel in Thread : " + Thread.currentThread().getName());
}
while (true) {
try {
logStr = readLine(fc);
if (logStr != null) {
System.out.println(logStr);
} else {
Thread.sleep(1000);
}
} catch (IOException|InterruptedException e) {
System.out.println("Exception occurred in Thread : " + Thread.currentThread().getName());
try {
fc.close();
} catch (IOException e1) {
}
break;
}
}
}
private String readLine(FileChannel fc) throws IOException {
ByteBuffer buffers = ByteBuffer.allocate(128);
// Standard size of a line assumed to be 128 bytes
long lastPos = fc.position();
if (fc.read(buffers) > 0) {
byte[] data = buffers.array();
boolean foundTmpTerminator = false;
boolean foundTerminator = false;
long endPosition = 0;
for (byte nextByte : data) {
endPosition++;
switch (nextByte) {
case -1:
foundTerminator = true;
break;
case (byte) '\r':
foundTmpTerminator = true;
break;
case (byte) '\n':
foundTmpTerminator = true;
break;
default:
if (foundTmpTerminator) {
endPosition--;
foundTerminator = true;
}
}
if (foundTerminator) {
break;
}
}
fc.position(lastPos + endPosition);
if (foundTerminator) {
return new String(data, 0, (int) endPosition);
} else {
return new String(data, 0, (int) endPosition) + readLine(fc);
}
}
return null;
}
verwendet Windows obligatorische Sperren für Dateien, wenn Sie die richtigen Aktien Flags angeben, während Sie öffnen. Wenn Sie ein Besetzt Datei öffnen möchten, müssen Sie Win32-API CreateFile
einen Griff mit der gemeinsamen Nutzung Fahnen FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE
.
Dies ist innerhalb des JDK an wenigen Stellen zum Öffnen von Dateien zum Lesen Attributs und Material verwendet, aber soweit ich sehen kann, es nicht exportiert / zur Verfügung Java-Klassenbibliothek Ebene. So müßten Sie eine native Bibliothek zu finden, das zu tun.
Ich denke, als eine schnelle Arbeit um Sie process.getInputStream()
vom Befehl "cmd /D/C type file.lck"
lesen