Dateien suchen und danach die Liste aktuell halten

Martin240

Grünschnabel
Hallo.

Ich arbeite gern mit Videos und Effekten und habe deshalb viele Videos auf meiner Platte rumfliegen. Das ganze natürlich über viele verschiedene Ordner verteilt und teilweise auch in Vergessenheit geraten. Deshalb habe ich mir überlegt ein Programm zu schreiben, dass mir eine Liste aller Videodateien auflistet und diese Liste dann auch aktualisiert. Natürlich sortierbar nach verschiedenen Kriterien. Danach wollte ich das ganze erweitern, damit ich die Dateien mit verschiedenen Programmen öffnen kann, evtl eine kleine Vorschau, Videoinformationen wie Auflösung, Codec, etc. anzeigen lassen, nur bin ich schon bei der Aktualisierung der Dateien auf kleinere Probleme gestoßen.

Ich habe im Moment 2 Klassen, einmal eine namens "Video", in der ich den Pfad speichere und später evtl noch zusätzliche Informationen reinschreibe, damit ich das ganze schön in Listenform präsentieren kann und eine Klasse "Searcher" mit der ich das Dateisystem nach Videos durchsuche und diese dann als Videoobjekt in eine LinkedList reinpacke. Jetzt tritt das erste Problem auf. Nicht mehr existente Videos zu entfernen ist kein Problem, einmal drüber laufen über die LinkedList und fragen ob die Datei noch existiert, wenn nein aus der LinkedList rauswerfen. Jetzt würde ich aber auch gerne neue Dateien dazupacken, nur leider habe ich keine Idee wie ich das "schön" programmieren kann. Natürlich gibts die Möglichkeit für jede Videodatei nochmal über die komplette LinkedList drüber zu laufen, zu schauen ob es drin ist und gegenbenfalls die Datei in die Liste reinpacken, aber das ist irgendwie unschön, oder? Wenn ich zum Beispiel all meine Festplatten als Ort angebe und er bei jeder Datei nochmal alle abfragt, dann gehts irgendwo Richtung quadratischer Laufzeit und ich habe gelernt sowas zu vermeiden ;-) Gibts da eventuell einen besseren Weg?

Oder sollte ich sogar über eine komplett andere Struktur nachdenken? Ich habe mir kurzzeitig überlegt eine Map zu erstellen in der ich den Pfad mit einem Objekt verbinde, in dem ich dann entsprechend die benötigten Infos reinschreiben könnte. Es wäre definitiv einfacher für das Aktualisierungsproblem, aber eine gute Lösung?

Ich bin auch für komplett andere Alternativen offen. Immer her mit dem Vorschlägen :)

Hier mal die paar Zeilen die ich eben auf die schnelle programmiert habe:

Code:
package priv.lfv;

import java.io.File;

public class Video {

	private File file = null;
	
	public Video(File file) {
		this.file = file;
	}
	
	public String getPath() {
		return file.getAbsolutePath();
	}
	
	public String getFileName() {
		return file.getName();
	}
	
	public boolean exists() {
		return file.exists();
	}
		
}

Code:
package priv.lfv;

import java.io.File;
import java.util.LinkedList;
import java.util.Stack;
import java.util.regex.Pattern;

public class Searcher {

	private LinkedList<Video> videoList = new LinkedList<Video>();
	
	public Searcher(LinkedList<File> paths, String ext) {
		// All paths will be given to this function, searching them one after another
		// ext is a regular expressions which describes the files we are looking for
		for(File path : paths) {
			findVideoFiles(path, ext);
		}
	}
	
	public LinkedList<Video> getVideoFiles() {
		return videoList;
	}
	
	private void findVideoFiles(File startDir, String ext) {
		// Simple file search function going through all subdirectories of the given one
		// If there is a match with the pattern just put it on the videolist
		Stack<File> dirs = new Stack<File>();
		Pattern p = Pattern.compile(ext, Pattern.CASE_INSENSITIVE);
		
		if(startDir.isDirectory()) {
			dirs.push(startDir);
		}
		
		while(dirs.size()>0) {
			// Unfortunately there is some trouble in reading directories like "System Volume Information" on windows machines
			// The test for non-null directory objects prevents some nasty NullPointerExceptions from happening
			File[] tempFiles = dirs.pop().listFiles();
			if(tempFiles!=null) {
				for(File file : tempFiles) {
						if(file.isDirectory() && file.canRead()) dirs.push(file);
						else if(p.matcher(file.getName()).matches()) videoList.add(new Video(file));
				}
			}
		}
	}

	
	public void updateVideoFiles() {
		// There are two things to be done here: checking files for existance and delete them if they are not present
		// and putting new files in the list if they appear on the hard drive. All the other files should be left untouched.
		for(Video vid : videoList) {
			if(!vid.exists()) videoList.remove(vid);
		}
		// TODO Get new files without clearing the whole LinkedList or running over it every time we find a new video file
	}
}
 
Hallo.
Jetzt würde ich aber auch gerne neue Dateien dazupacken, nur leider habe ich keine Idee wie ich das "schön" programmieren kann. Natürlich gibts die Möglichkeit für jede Videodatei nochmal über die komplette LinkedList drüber zu laufen, zu schauen ob es drin ist und gegenbenfalls die Datei in die Liste reinpacken, aber das ist irgendwie unschön, oder? Wenn ich zum Beispiel all meine Festplatten als Ort angebe und er bei jeder Datei nochmal alle abfragt, dann gehts irgendwo Richtung quadratischer Laufzeit und ich habe gelernt sowas zu vermeiden ;-) Gibts da eventuell einen besseren Weg?

Muß es denn eine Liste sein? Die Reihenfolge der einzelnen Files ist doch unerheblich, oder?
Dann mach doch ein Set (TreeSet oder HashSet) draus, da sind die Lookup-Frage (mit Set.contains(element) ) theoretisch schneller als über die Liste zu gehen.

Thinker
 
TreeSet ist sortiert :D
Genau wie SortedSet :)

TreeSet implementiert aber das NavigableSet interface, wodurch es mehr Funktionen anbietet zum durchschauen :)

Da musst du selbst in der API schauen, was dir ausreicht.
 
Wie sieht das denn mit den zusätzlichen Informationen aus, ich würde gerne zum Beispiel Codec, Auflösung, Länge, etc. später in einer Liste formatiert darstellen und dann halt auch dementsprechend das ganze sortieren können in der Ansicht. Wie stell ich das am besten an? Ich habe noch nie mit Tabellenstrukturen gearbeitet. Muss ich das erst auslesen, irgendwo reinpacken und dann anzeigen oder kann ich das auch direkt berechnen lassen während er das ganze anzeigt? Da dürfte die Sortierung dann wohl einen Strich durch die Rechnung machen.

Meine erste Idee wäre jetzt spontan gewesen das ganze in eine Map zu packen, wie oben schon beschrieben, mit dem Pfad zur Datei als ersten Teil und die ganzen Eigenschaften als Klasse als zweiten Teil. Nur wie ordne ich das ganze dann? Ich denke Comparable wäre da wohl hilfreich, das müsste ich mir dann aber nochmal alles ansehen.

Wie immer bin ich für andere Vorschläge natürlich offen :)
 

Neue Beiträge

Zurück