Auffinden von xml-Dateien und weitergabe an Parser

OKShaitan

Grünschnabel
Hallo,

ich möchte einen Reader schreiben, der minutenweise prüft, ob in einem absoluten Pfad eine neue xml-Datei (Bestellung) eingegangen ist. Den Namen dieser Datei weiß ich allerdings nicht vorher.

Später möchte ich diese Datei dann einem XMLParser (DOM) unter einem festen Dateinamen zur Verfügung stellen und den Parser aufrufen (aber nur, wenn eine neue Bestellung da ist).

Ich bin mir nicht ganz so sicher, ob ich nun die "alten" Dateien dann löschen sollte oder ob ich noch eine Methode zum Vergleichen implementieren sollte.

Einige Zeilen Code habe ich bereits, wenn aber einer mal drüber schauen würde, wäre das echt klasse. Habe nämlich festgestellt, daß ich Probleme habe beim API verstehen.

Der Thread ist noch nicht implementiert, genauso wie der Parser-Aufruf. Da es keine GUI gibt, wird die Ausgabe auf der Konsole erfolgen, und wenn wir soweit sind, in einem LogBuch abgespeichert (gibt es davor evtl. schon implementierten Code?)

Code:

Code:
import java.rmi.*;
import java.io.*;

/**
 *
 * erstellt: 11.07.04
 *
 *
 * Der Reader wird vom Server initiiert und prüft minutenweise, ob eine neue
 * XML-Datei im StandardVerzeichnis abgelegt worden ist. Wenn ja, wird der
 * Name der Datei an den XMLParser weitergeleitet und die Datei in einen
 * temporären Ordner weitergeleitet.
 *
 */

public class Reader
    extends Thread {

  public String fileName; //Name der DAtei
  public String temp;
  public String dest = "c:/"; //Ziel für XML-File
  public static File file; //leere Datei
  public String prefile = "order"; //Präfix für temporären Dateinamen
  public String suffile = ".xml"; //Suffix für temporären Dateinamen
  public File tempFile; //temporäre Datei zum Löschen

  //Default-Konstruktor
  public Reader() {}

//Methoden

//Thread, der vom Server gestartet wird und sich für eine Minute schlafen legt
  public void run() {

  }

  /**
   * Auslesen des neuen XML-Dateinamens, kopieren in eine temporäre Datei
   * zum Auslesen für den XML-Parser.
   * @return Rückgabe
   */
  public String search() {
    //Durchsuchen des absoluten Pfades nach neuer XML-Datei
    if (fileName.toLowerCase().endsWith(".xml")) {
      //Name der Datei holen
      fileName = getName();
      System.out.println("Es wurde die Datei " + fileName + "gefunden");
      //leere Datei mit bestimmten Namen erzeugen
      createTempFile(prefile, suffile);
      System.out.println("leere Datei zum Auslesen wurde erstellt");
      //leere Datei als String umformen, um Dateiinhalte zu übertragen
      dest = file.getName();
      //Dateiinhalte kopieren
      copy(fileName, dest);
      System.out.println("Dateiinhalte wurden übernommen");
      //Löschen der alten XML-Datei
      fileDel(fileName);
    }
    else {
      System.out.println("Keine neue Bestellungen vorhanden");
    }
    return fileName;
  }

  /**
   * Erstellen einer leeren Datei mit einem vorher bestimmten Dateinamen
   * @param prefile Präfix für temporären Dateinamen
   * @param suffile Suffix für temporärem Dateinamen
   * @return Rückgabe des Dateinamens
   */
  public static File createTempFile(String prefile, String suffile) {
    return file;
  }

  /**
   * Löschen der Überwiesenen Datei
   * @param fileName Filedeskriptor zum Löschen der Datei
   */
  public void fileDel(String fileName) {
    //Filedeskriptor anlegen
    tempFile = new File(fileName);
    System.out.println("Datei " + tempFile + "wird gelöscht!");
    //Löschen der Datei
    tempFile.delete();
  }

  /**
   * Kopieren der aktuellen XML-Datei in TEMP-Verzeichnis
   * @param src Quellverzeichnis
   * @param dest Zielverzeichnis
   */
  public void copy(String fileName, String dest) {
    try {
      copy(new FileInputStream(fileName), new FileOutputStream(dest));
      System.out.println("Datei wurde in Verzeichnis kopiert");
    }
    catch (IOException e) {
      e.printStackTrace();
    }
  }

  /**
   * Öffnen der Datei, damit diese kopiert werden kann
   * @param fis Stream, der die Quelldatei öffnet
   * @param fos Stream, der die Zieldatei öffnet
   */
  static void copy(InputStream fis, OutputStream fos) {
    try {
      byte buffer[] = new byte[0xffff];
      int nbytes;
      //Puffern der Bytes
      while ( (nbytes = fis.read(buffer)) != -1)

        //Schreiben der Bytes
        fos.write(buffer, 0, nbytes);
    }
    catch (IOException e) {
      e.printStackTrace();
    }
    //Schließen der Datei bzw. der Dateiströme
    finally {
      if (fis != null)
        try {
          fis.close();
        }
        catch (IOException e) {
          e.printStackTrace();
        }

      try {
        if (fos != null)
          fos.close();
      }
      catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
}
 
Hallo!

Der Thread ist noch nicht implementiert, genauso wie der Parser-Aufruf.

Hab mich schon gewundert weshalb die run Methode nicht implementiert ist ....

Denke es ist sinnvoll alle Dateien nach dem Verarbeiten in ein anderes Verzeichnis zu kopieren. Jedoch sollten die Fehlerhaften u.U. in einem anderen Verzeichnis landen als die "korrekten" Dateien.

Dein CreateTempFile kannst du dir eigentlich sparen, da die Klasse File eine solche Methode schon von Haus aus mitbringt. Weiterhin gibt es (IMHO) in der FAQ von dclj.de eine schicke Variante einer copy Methode um Dateien zu kopieren.

Könntest ja sowas wie hier versuchen:
(Fehlerbehandlung fehlt)

Code:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class FileScanner {

	public static void main(String[] args) {
		File src = new File("c:/tmp1/FileScanner");
		File dest = new File("c:/tmp1/FileScannerDepot");
		File errorDir = new File("c:/tmp1/FileScannerErrors");
		Scanner scanner = new FileScanner().new Scanner(src, dest, errorDir);
		scanner.start();
	}

	class Scanner extends Thread {

		private File src;
		private File dest;
		private File errorDir;
		private List newFiles;
		private Map errors;
		private List lstFiles;

		public Scanner(File src, File dest, File errorDir) {
			this.src = src;
			this.dest = dest;
			this.errorDir = errorDir;
			this.errors = new HashMap();
			this.lstFiles = new ArrayList();
			//Damit wir nicht so viel Leistung vom System ziehen
			this.setPriority(Thread.MIN_PRIORITY);
		}

		public void run() {
			try {
				while (true) {
					//Damit wir nicht so viel Leistung vom System ziehen
					Thread.sleep(500L);
					File[] files = src.listFiles();

					if (files.length == 0)
						continue;

					boolean found = false;

					for (int i = 0; i < files.length; i++) {
						String fName = files[i].getName();
						if (fName.substring(fName.indexOf(".")+1)
							.equalsIgnoreCase("xml")) {
							found = true;
							log("New XML file Detected: " + fName);
							lstFiles.add(files[i]);
							processFile(files[i]);
						}
					}

					//wenn keine XML Dateien gefunden wurden...
					if (!found)
						continue;

					int size = lstFiles.size();
					for (int i = 0; i < size; i++) {
						File file = (File) lstFiles.get(i);
						String str = (String) errors.get(file);
						if (str != null) {
							log(str + " -> " + file.getName());
							//hier nun Sonderbehandlung für das jeweilige file ....
							processErrorFile(file);
						}
						file.delete();
					}
					errors.clear();
					lstFiles.clear();
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		/**
		 * @param file
		 */
		private void processErrorFile(File file) {
			log("ProcessingErrorFile: " + file.getName());
			try {
				copyFile(
					file,
					new File(errorDir.getAbsolutePath() + "/" + file.getName()),
					128,
					true);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		/**
		 * @param file
		 */
		private void processFile(File file) throws IOException {
			log("Processing File: " + file.getName());
			//irgendwas mit der Datei machen...
			//Fehler simulieren:
			if (Math.random() * 10 < 5) {
				errors.put(file, "Datei korrupt!");
			} else {
				//Datei ins Fehleraufberwahrungsverzeichnis kopieren...
				copyFile(
					file,
					new File(dest.getAbsolutePath() + "/" + file.getName()),
					128,
					true);
			}
		}

		private void log(String msg) {
			System.out.println(msg);
		}

		/**
		 * 
		 * Copy Methode aus der dclj.de FAQ
		 * 
		 * @param src
		 * @param dest
		 * @param bufSize
		 * @param force
		 * @throws IOException
		 */

		private void copyFile(File src, File dest, int bufSize, boolean force)
			throws IOException {

			if (dest.exists()) {
				if (force) {
					dest.delete();
				} else {
					throw new IOException(
						"Cannot overwrite existing file: " + dest.getName());
				}
			}
			byte[] buffer = new byte[bufSize];
			int read = 0;
			InputStream in = null;
			OutputStream out = null;
			try {
				in = new FileInputStream(src);
				out = new FileOutputStream(dest);
				while (true) {
					read = in.read(buffer);
					if (read == -1) {
						//-1 bedeutet EOF
						break;
					}
					out.write(buffer, 0, read);
				}
			} finally {
				// Sicherstellen, dass die Streams auch
				// bei einem throw geschlossen werden.
				// Falls in null ist, ist out auch null!
				if (in != null) {
					//Falls tatsächlich in.close() und out.close()
					//Exceptions werfen, die jenige von 'out' geworfen wird.
					try {
						in.close();
					} finally {
						if (out != null) {
							out.close();
						}
					}
				}
			}
		}

	}
}

Da es keine GUI gibt, wird die Ausgabe auf der Konsole erfolgen, und wenn wir soweit sind, in einem LogBuch abgespeichert (gibt es davor evtl. schon implementierten Code?)

Dazu gibt es zig gute Bibliotheken von dem normalen Logger API von J2SDK 1.4 an bis zum Log4j dem König der Logging APIs.

http://jakarta.apache.org/commons/logging/
http://logging.apache.org/log4j/docs/
http://java.sun.com/j2se/1.4.2/docs/guide/util/logging/


Gruß Tom
 
Fehlerhafte Dateien sollte es im Allgemeinen nicht geben, da die XML-Dateien von unseren Prof vorgegeben werden und auf Fehlerlosigkeit geprüft wurden. Oder meintest du bei Fehler beim Parsen?

Dein Code hat im Gegensatz zu meinem ja schon den Thread mit eingebaut und fängt auch schon Fehler ab. So weit bin ich gestern nicht mehr gekommen. Bin auch nicht gerade der schnellste Programmierer.

Aber meine Frage wäre auch noch, ob mein Code (bis auf die Teile, die noch fehlen) auch funktionstüchtig wäre bzw. sinnvolle Ansätze hat. Was könnte ich denn besser machen?
 

Neue Beiträge

Zurück