ich bin gerade beim Thema File-Writer/Reader und habe ein kleines Problem.
Ich würde gerne per Scanner einen Dateinamen einlesen lassen, welcher anschließend im FileWriter für den Namen der Datei genutzt wird, das habe ich auch hinbekommen, allerdings kann ich anschließend im FileReader nicht mehr auf die Variable "dateiName" zugreifen, da diese ja nur lokal in der Methode schreibeInDatei() sichtbar ist.
Wie löse ich das Problem am besten?
Java:
importjavafx.application.Application;importjavafx.stage.Stage;importjava.io.*;importjava.util.Scanner;/**
* @author
*/publicclassIOStringextendsApplication{publicstaticvoidmain(String[] args)throwsIOException{schreibeInDatei();leseAusDatei();}/**
* Liest Dateinamen und Dateitext als Strings ein und schreibt anschließend Dateitext in eine generierte Datei
*
* @throws IOException
*/publicstaticvoidschreibeInDatei()throwsIOException{Scanner input =newScanner(System.in);System.out.println("Text der in Datei geschrieben werden soll: ");String dateiText = input.next();System.out.println("Namen der Datei eingeben: ");String dateiName = input.next();
input.close();FileWriter fileWriter =newFileWriter(dateiName);BufferedWriter bufferedWriter =newBufferedWriter(fileWriter);
bufferedWriter.write(dateiText);
bufferedWriter.close();}/**
* Liest Text aus oben erstellter Datei
*
* @throws IOException
*/publicstaticvoidleseAusDatei()throwsIOException{FileReader fileReader =newFileReader(dateiName);// <- cannot resolve symbol "dateiName"BufferedReader bufferedReader =newBufferedReader(fileReader);
bufferedReader.close();}@Overridepublicvoidstart(Stage primaryStage)throwsException{}}
1. Das ganze ist ganz bestimmt keine JavaFX Application, also kannst du das `extends Application` entfernen.
2. Lagere das Abfragen des Dateinamens per Scanner in eine separate Methode aus, die eben den eingegebenen Dateinamen als Rückgabewert zurück gibt.
3. Führe einen neuen String Parameter in leseAusDatei und schreibeInDatei ein, der der Dateiname ist, den du von der Methode aus 2. zurückgegeben bekommst. Das heißt, du rufst diese beiden Methoden dann mit einem Argument auf.
Habe den Code entsprechend angepasst, er spuckt mir aber folgendes aus :/
Java:
Exception in thread "main" java.util.NoSuchElementException:No line found
at java.base/java.util.Scanner.nextLine(Scanner.java:1651)
at IOString.nameEinlesen(IOString.java:28)
at IOString.leseAusDatei(IOString.java:57)
at IOString.main(IOString.java:65)
Java:
importjava.io.*;importjava.util.Scanner;/**
* @author
*/publicclassIOString{publicstaticStringtextEinlesen(){Scanner input =newScanner(System.in);System.out.println("Text der in Datei geschrieben werden soll: ");String dateiText = input.nextLine();
input.close();return dateiText;}publicstaticStringnameEinlesen(){System.out.println("Dateinamen eingeben");Scanner input =newScanner(System.in);String dateiName = input.nextLine();return dateiName;}/**
* Liest Dateinamen und Dateitext als Strings ein und schreibt anschließend Dateitext in eine generierte Datei
*
* @throws IOException
*/publicstaticvoidschreibeInDatei()throwsIOException{FileWriter fileWriter =newFileWriter(nameEinlesen());BufferedWriter bufferedWriter =newBufferedWriter(fileWriter);
bufferedWriter.write(textEinlesen());
bufferedWriter.close();}/**
* Liest Text aus oben erstellter Datei
*
* @throws IOException
*/publicstaticvoidleseAusDatei()throwsIOException{FileReader fileReader =newFileReader(nameEinlesen());BufferedReader bufferedReader =newBufferedReader(fileReader);
bufferedReader.close();}publicstaticvoidmain(String[] args)throwsIOException{schreibeInDatei();leseAusDatei();}}
Deine Lösung entspricht ganz und garnicht dem, was ich schrieb. Bitte lese noch einmal ganz ganz genau meinen Vorschlag. Weißt du, was ein Methodenparameter ist?
1. Das ganze ist ganz bestimmt keine JavaFX Application, also kannst du das `extends Application` entfernen.
2. Lagere das Abfragen des Dateinamens per Scanner in eine separate Methode aus, die eben den eingegebenen Dateinamen als Rückgabewert zurück gibt.
3. Führe einen neuen String Parameter in leseAusDatei und schreibeInDatei ein, der der Dateiname ist, den du von der Methode aus 2. zurückgegeben bekommst. Das heißt, du rufst diese beiden Methoden dann mit einem Argument auf.
die JavaFX Referenz habe ich entfernt, das Abfragen des Dateinamens habe ich wie du vorgeschlagen hast in eine separate Methode nameEinlesen() ausgelagert.
Bezüglich dem 3. Punkt bin ich etwas verwirrt, also klar sind mir Methodenparameter bekannt allerdings würde das ganze beim Aufruf in der main() ja dann so aussehen -> schreibeInDatei(textEinlesen()) und leseAusDatei(nameEinlesen()) führt er dann nicht alles doppelt und dreifach aus?
Aber auch wenn es nicht das ist, was vorgeschlagen wurde möchte ich den Fehler kurz erläutern:
In textEinlesen schließt du den Scanner auf Sytem.in und damit auch System.in. Wenn du dann später erneut versuchst, aus System.in mit einem neuen Scanner zu lesen, dann ist System.in ja schon geschlossen und Du bekommst beim Versuch diese Exception.
Scanner sollte man auch nicht so massiv erstellen. Mein Vorschlag bei sowas ist ein public static Scanner der immer genutzt wird und nie geschlossen.
Nein. Das ist eine ganz normale lokale Variable in einer Methode. Genauso wie der Scanner oder der FileReader/FileWriter.
Nochmal um es ganz deutlich zu machen: