Rekursiv muss dass laufen!

  • Themenstarter Themenstarter JayJay
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
J

JayJay

Gast
Ja Hallo ich habe ein problem mit einem programm an dem ich gerade arbeite. Das programm "watched" über änderungen in einem base folder, bsw: c:\TestFolder , und ich brauche es Rekursiv.
Rekursiv im sinne, dass wenn eine File, isFile() es dass machen soll was es schon macht, dass passt, nur wenn es eine subdirectory innerhalb der base directory findet, also isDirectory(), dann soll es rekursiv in diesem folder wieder die run methode laufen lassen!!!

Mir ist schon klar wie es rekursiv laufen sollte, indem die run() methode innerhalb der eigenen methode aufgerufen wird.

Ich habe vieles versucht nur hab ich noch so einige fehler im programm. Hier ist der code:


public DirWatcher(String path, String filter) throws FileNotFoundException {
this.path = path;
dfw = new DirFilterWatcher(filter);
filesArray = new File(path).listFiles(dfw);
validateDirectory(new File(path));

// transfer to the hashmap be used a reference and keep the
// lastModfied value
for (int i = 0; i < filesArray.length; i++) {
dir.put(filesArray, new Long(filesArray.lastModified()));
}

}

protected abstract void onChange(File file, String action);

public final void run() {
HashSet<File> checkedFiles = new HashSet<File>();

// scanning the files and checking for modification/addition
for (int i = 0; i < filesArray.length; i++) {
Long current = (Long) dir.get(filesArray);

checkedFiles.add(filesArray);
if (current == null) {
// new file
dir.put(filesArray, new Long(filesArray.lastModified()));
onChange(filesArray, "new File\\Directory added");
} else if (current.longValue() != filesArray.lastModified()) {
// modified file ??!!! Distiguish between file and foldeer
dir.put(filesArray, new Long(filesArray.lastModified()));
onChange(filesArray, "File or Directory has been modified");
}

}

// now check for deleted files
Set ref = ((HashMap) dir.clone()).keySet();
ref.removeAll((Set) checkedFiles);
Iterator it = ref.iterator();
while (it.hasNext()) {
File deletedFile = (File) it.next();

dir.remove(deletedFile);
onChange(deletedFile, "deleted");
}
}



Ich bin die sache vielleicht etwas kompliziert angegangen mit den arrays+hashmap+hashset. Was hilfreich wäre ist wo und wie genau ich dieses rekursiv laufen lassen kann, da ich probleme habe mit den typ variablen um dies zu machen. Ich bekomme immer eine fehler meldung: "Cannot instantiate this method", wenn ich etwas versuche.

Danke im vorraus
 
Ähm kapsel mal deinen Code bitte in einem Code-Tag. Dann können wir den vielleicht auch lesen. 😉

bye Saxony
 
Oh ok

Code:
public DirWatcher(String path, String filter) throws FileNotFoundException { 
this.path = path; 
dfw = new DirFilterWatcher(filter); 
filesArray = new File(path).listFiles(dfw); 
validateDirectory(new File(path)); 

// transfer to the hashmap be used a reference and keep the 
// lastModfied value 
for (int i = 0; i < filesArray.length; i++) { 
dir.put(filesArray[i], new Long(filesArray[i].lastModified())); 
} 

} 

protected abstract void onChange(File file, String action); 

public final void run() { 
HashSet<File> checkedFiles = new HashSet<File>(); 

// scanning the files and checking for modification/addition 
for (int i = 0; i < filesArray.length; i++) { 
Long current = (Long) dir.get(filesArray[i]); 

checkedFiles.add(filesArray[i]); 
if (current == null) { 
// new file 
dir.put(filesArray[i], new Long(filesArray[i].lastModified())); 
onChange(filesArray[i], "new File\\Directory added"); 
} else if (current.longValue() != filesArray[i].lastModified()) { 
// modified file ??!!! Distiguish between file and foldeer 
dir.put(filesArray[i], new Long(filesArray[i].lastModified())); 
onChange(filesArray[i], "File or Directory has been modified"); 
} 

} 

// now check for deleted files 
Set ref = ((HashMap) dir.clone()).keySet(); 
ref.removeAll((Set) checkedFiles); 
Iterator it = ref.iterator(); 
while (it.hasNext()) { 
File deletedFile = (File) it.next(); 

dir.remove(deletedFile); 
onChange(deletedFile, "deleted"); 
} 
} 
[\code]
 
Code:
public DirWatcher(String path, String filter) throws FileNotFoundException
{
	this.path = path;
	dfw = new DirFilterWatcher(filter);
	filesArray = new File(path).listFiles(dfw);
	validateDirectory(new File(path));

//		 transfer to the hashmap be used a reference and keep the
//		 lastModfied value
	for (int i = 0; i < filesArray.length; i++)
	{
		dir.put(filesArray[i], new Long(filesArray[i].lastModified()));
	}
}

protected abstract void onChange(File file, String action);

public final void run()
{
	HashSet<File> checkedFiles = new HashSet<File>();

//		 scanning the files and checking for modification/addition
	for (int i = 0; i < filesArray.length; i++)
	{
		Long current = (Long) dir.get(filesArray[i]);
	
		checkedFiles.add(filesArray[i]);
		if (current == null)
		{
//		 new file
			dir.put(filesArray[i], new Long(filesArray[i].lastModified()));
			onChange(filesArray[i], "new File\\Directory added");
		}
		else if (current.longValue() != filesArray[i].lastModified())
		{
//		 modified file ??!!! Distiguish between file and foldeer
			dir.put(filesArray[i], new Long(filesArray[i].lastModified()));
			onChange(filesArray[i], "File or Directory has been modified");
		}
	}

//		 now check for deleted files
	Set ref = ((HashMap) dir.clone()).keySet();
	ref.removeAll((Set) checkedFiles);
	Iterator it = ref.iterator();
	while (it.hasNext())
	{
		File deletedFile = (File) it.next();
	
		dir.remove(deletedFile);
		onChange(deletedFile, "deleted");
	}
}
sein code in leserlicherer form -> #not modified#
 
Hiho,

nunja ohne jetzt direkten Bezug zu deinem Code zu nehmen.
Im allgemeinen geht das wie hier beschrieben.

Falls der Link irgend wann mal nicht mehr gehen sollte:

Code:
//author: Marco Schmidt

import java.io.File;

public class scantree {
    public static void main(String[] args) {
        // Programm muss einen Verzeichnisnamen als Parameter haben
        File dir = new File(args[0]);
        scan(dir);
    }

    public static void scan(File dir) {
        // Liste aller Dateien und Unterverzeichnisse holen
        String[] entries = dir.list();
        if (entries == null || entries.length < 1) {
            return;
        }
        for (int i = 0; i < entries.length; i++) {
            File entry = new File(dir, entries[i]);
            if (entry.isDirectory()) {
                scan(entry); // rekursiv ins Unterverzeichnis verzweigen
            } else {
                // entry ist eine Datei
                System.out.println(entry);
            }
        }
    }
}

Übrigens: 5. Eintrag bei google / Suchbegriff: java rekursiv verzeichnisse lesen
😀

Dabei findet man auch eine Lösung aus dem Buch Java ist auch eine Insel, welche aber keinen expliziten Rekursionsaufruf durchführt sondern mit Stack und List arbeitet.

🙂

bye Saxony
 
Ja die Logik passt, nur hatte ich schon ne methode die mir den Inhalt der subdirectories auflistet.

Code:
public static List recursiveDir(File startDir) throws FileNotFoundException {
	
		validateDirectory(startDir);//puts in path
		List result = new ArrayList();

		File[] filesAndDirs = startDir.listFiles();
		List filesDirs = Arrays.asList(filesAndDirs);
		Iterator filesIter = filesDirs.iterator();
		File file = null;
		while (filesIter.hasNext()) {
			file = (File) filesIter.next();
			result.add(file); // always add, even if directory
			
			if (file.isDirectory()) { //better
				List deeperList = recursiveDir(file);
				result.addAll(deeperList);
		}
		}
		Collections.sort(result);
		return result;
		
		}

Das eigentliche problem ist die run() methode rekursiv aufzurufen, dass die jeweiligen subdirectories dann überwacht und mir die datai änderung innerhalb aller directories mitteilt.
Das programm ist ein überwachungsprogramm für änderungen innerhalb einer main Directory. Der andere teil ist das nachdem änderungen erkannt wurden dass eine automatische email an die jeweiligen personen verschickt werden per JavaMail natürlich. Den teil hab ich schon, nur brauch ich eine kombination der run() methode die ich oben geposted hab die mit der logik von ScanTree läuft.
 
Hiho,

so naja ich hab mal was gebastelt.

Folgender Code durchsucht permanent ein Verzeichnis. Sollten sich Dateien geändert haben, wird dies abgefangen und die veränderte Datei angezeigt. An dieser Stelle kannste dann deine Mailfunktion rein tun.

Code:
import java.io.File;
import java.util.Iterator;
import java.util.Vector;

public class Dir {

	private Vector<MyFile> currentFiles;
	private Vector<MyFile> oldFiles;

	public static void main(String[] args) {

		Dir dir = new Dir();
		dir.run(new File("c:\\test\\"));
	}

	public Dir() {

		this.currentFiles = new Vector<MyFile>();
		this.oldFiles = new Vector<MyFile>();
	}

	public void run(File aFile) {

		while (true) {

			this.oldFiles = (Vector<MyFile>)(this.currentFiles.clone());
			this.currentFiles.removeAllElements();
			
			try {
				Thread.sleep(1000);
			} catch (Exception ex) {}
			
			this.getCurrentFiles(aFile);			
			this.checkModified();		
		}
	}

	public void getCurrentFiles(File aFile) {

		String[] entries = aFile.list();

		if (entries == null || entries.length < 1) {
			return;
		}

		for (int i = 0; i < entries.length; i++) {
			File entry = new File(aFile, entries[i]);
			if (entry.isDirectory()) {

				getCurrentFiles(entry);
			} else {

				this.currentFiles.add(new MyFile(entry.getAbsolutePath(), entry.lastModified()));
			}
		}
	}

	public void checkModified() {

		Iterator<MyFile> iter = this.currentFiles.iterator();
		MyFile current;
		MyFile old;
		while (iter.hasNext()) {

			current = iter.next();
			old = this.getOldFile(current.getPath());

			if (old != null) {

				System.out.println(current.getLastModified());
				System.out.println(old.getLastModified());
				
				if (current.getLastModified() != old.getLastModified()) {

					System.out.println("jetzt ne mail "
							+ current.getPath());
				}
			}
		}
	}

	public MyFile getOldFile(String aPath) {

		MyFile erg = null;

		Iterator<MyFile> iter = this.oldFiles.iterator();
		MyFile old;

		while (iter.hasNext()) {

			old = iter.next();

			if (old.getPath().equals(aPath))
				return old;
		}

		return erg;
	}
}

und noch die MyFile

Code:
public class MyFile {

	private long modified;
	private String path;

	public MyFile(String aPath, long aModified) {

		this.path = aPath;
		this.modified = aModified;
	}

	public long getLastModified() {

		return this.modified;
	}
	
	public String getPath() {

		return this.path;
	}
}

Is erstma ne schnelle Lösung, die man sicher noch überarbeiten könnte/sollte.

Analog zu checkModified kannste dann halt auch die Sache mit gelöschten Dateien machen.

bye Saxony
 
Ja wunderbar, dass mit der delete hab ich auch hinbekommen. 🙂

Noch eine letzte frage hab ich noch.
Wenn jetzt neue dateien hinzugefügt werden in die Verzeichnisse,
wie würde der if clause aussehen.
Ich weiss das es recht simple iss, aber klappt bei mir net so ganz.

Vielen Dank für alles
 
Also mein problem ist dass bei der methode

Code:
public void checkModified() {
		Iterator<MyFile> iter = this.currentFiles.iterator();
		MyFile current;
		MyFile old;
		
		while (iter.hasNext()) {

			current = iter.next();
			old = this.getOldFile(current.getPath());
			
			if (old != null) {
				
				// System.out.println(current.getLastModified());
				// System.out.println(old.getLastModified());
		
				if (current.getLastModified() == null) { //hier liegt das problem
// das geht nicht weil: "The operator == is undefined for the argument type(s) long, null" 
					System.out.println("New File has been added: "+current.getPath() + " on: " + new Date());
				}
				if (current.getLastModified() != old.getLastModified()) {

					System.out.println("The File: " + current.getPath()
							+ " has been changed on: " + new Date());
					// System.out.println("jetzt ne mail " + current.getPath());
				}
			}
		}
	}

Weiss jemand einen weg vorbei oder besser?
 
primitive Typen sind "keine" objekte

also

int = 0
long = 10

also nix null

dann auch
if( myInt == 0)
 
Ja klar war doch so einfach 🙂

Also dieser Thread ist fertig wie kann ich dass denn abticken.

Vielen dank Herr Gast

Aso die Lösung falls die jemand will:
Naja man muss nur eine else clause einbauen unzw. im gegensatz zu: "if (old != null) { "
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben