Java File I/O

Vulpecula

Commander
Registriert
Nov. 2007
Beiträge
2.241
Moinsen!

Ich hab hier eine Methode, mit der ich momentan nicht so richtig glücklich bin. Was mich am meisten stört, ist die Tatsache, dass das reine Öffnen (inkl. dem Behandeln von Fehlern) und das Auslesen der Daten quasi in ein und der selben Methode stattfindet. Wenn ich jetzt allerdings auf die Idee komme, Binärdaten zu lesen, dann müsste ich eine weitere Methode schreiben, in der wieder die ganzen Exceptions abgefangen werden. Zusätzlich habe ich noch eine eine Debug-Funktionalität, die ständig Daten in eine Datei schreibt, was ebenfalls abgesichert werden muss, damit mir das Programm nicht unerwartet aussteigt. Eigentlich würde ich das ganze gerne etwas universeller haben, d.h. dass alles etwas stärker modularisiert sein soll. Hat jemand von Euch vielleicht ein paar Tipps, wie man das besser hinbekommt?

Code:
public static void openFile(String file) throws IOException, FileNotFoundException
{
    try
    {
        fileInput = new Scanner(new BufferedReader(new FileReader(file)));
        while (fileInput.hasNext())
        {
            fileContent.add(fileInput.next().toLowerCase());
        }
    } 
    catch(FileNotFoundException e)
    {
        System.out.println("Datei '" + file + "' nicht gefunden.");                
    }
    catch(IOException e)
    {
        System.out.println("Datei '"+ file + "' konnte nicht geöffnet werden.");
    }
    finally
    {
        if (fileInput != null)
        {
            fileInput.close();
            // gelesene Daten verarbeiten
        }
    }
}
 
Nutzt Du Java7? Dann übernimmt die VM für Dich das Schließen der Datei bzw. das Aufräumen. Du musst Dich dann nicht um die ganzen checked Exceptions kümmern.

Das geht ungefähr so:

try (Reader r = new Reader(new Stream(new Irgendwas-Decorator ...))) {
// hier die eigentliche Logik auf dem Reader
}

// das wars, kein catch und kein finally nötig.

Cool, oder? :D
 
Na im Prinzip steht da
Code:
    public static void openFile(String file) throws IOException, FileNotFoundException {
        try (Scanner fileInput = new Scanner(new BufferedReader(new FileReader(file)))) {
            while (fileInput.hasNext()) {
                fileContent.add(fileInput.next().toLowerCase());
            }
        }
    }

Bei deinem Code behandelst du gleichzeitig die möglichen Exceptions, während du sie aber auch nach draußen wirfst. Eins macht nur Sinn und das musst du selbst entscheiden, ob es den client clode (d.h. den restlichen Code, der diese Methode nutzt) interessiert, ob es darin geknallt hat.

P.S.: für große Dateien rennst du da in out of memorys. Warum prozessierst du nicht on the fly die Zeilen?
 
@Faust2011: Ich nutze Java 8. Aber ich bin mir nicht sicher, ob es so clever ist, sich alleine auf die JVM zu verlassen. Außerdem muss ich ja irgendwas ausgeben, wenn die Datei z.B. nicht vorhanden ist.

@Tumbleweed: Kannst Du etwas genauer ausführen, was Du meinst? Oh und: Das Zeilenweise prozessieren würde meinen restlichen Parser extrem verkomplizieren. :(
 
Du kannst Ressourcen nicht besser schließen als die JVM, da mach dir mal keine Illusionen. :p

Gut, wenn es für deine Logik relevant ist alles im Speicher zu haben, dann muss das eben so. Was hättest du denn gern genauer ausgeführt? Das mit den Exceptions? Na du hast sowohl throws in der Methodensignatur als auch catch-Blöcke im Methodenkörper. Eins macht nur Sinn. Ich hätte nicht mal gedacht, dass das kompiliert. :p -> Entweder fangen ODER werfen. Vielleicht solltest du dich genau zu dem Thema nochmal belesen, wenn dir das noch nicht ganz klar ist.
 
Ohne Dir zu nahe zu treten, aber ich würde mir zuerstmal Gedanken machen über das Software-Design Deines Scanner. Ein paar Überlegungen:

- openFile ist static? WTF!

- Die Methode deklariert per throws diverse Exceptions, aber eigentlich fängst Du diese bereits innerhalb der Methode (und machst keine Rethrows)

- Wer trägt die Verantwortlichkeit für das Sicherstellen der Existenz der Datei? Oder andersrum: ist die Verantwortlichkeit von openFile() tatsächlich, die Datei direkt in den Scanner zu stecken? Sollte sie nicht besser einfach die geöffnete Datei zurückgeben?
 
@Tumbleweed: Hab mich nochmal etwas in das Thema Exceptions eingelesen. Jetzt verstehe ich auch, was das angesprochene Problem mit dem throws und dem try...catch ist.

@Faust2011: Das try-with-resources Statement ist wirklich eine feine Sache. Ich bin allerdings noch am überlegen, wie dann eine Methode aussehen müsste, die mir eine offene Datei zurückgibt, bzw. wie eine Klasse aussieht in der ich das Datei-Handling (Input/Output) abwickle. Eigentlich müsste es dann doch okay sein, wenn ich statt Werfen dann die I/O Fehler in der Klasse selbst behandle, oder? OpenFile ist deswegen static, weil ich die Methode irgendwann in ein anderes Projekt kopiert habe, um daran rumzubalsteln.
 
Zuletzt bearbeitet:
Klar kann man eine Exception direkt in der Methode behandeln
Würde dann so aussehen:

Code:
	public static void openFile(String filename) 
{
	try(BufferedReader br = Files.newBufferedReader(Paths.get(filename)))
//Scanner brauchst du eigentlich auch nicht
	{
		while(br.ready())
		{
			fileContent.add(br.readLine().toLowerCase());
		}
	}
	catch(IOException e)
	{
		e.printStackTrace();
	}
}
 
Zuletzt bearbeitet:
Zurück
Oben