RandomAccessFile int und String gleichzeitig in einer Datei

matze86

Bekanntes Mitglied
Hallo, ich möchte mit der Klasse RandomAccessFile einen int- und einen String-Wert in einer binären Datei schreiben.

Zuerst den Int-Wert danach den String.
Habe das mal getestet, aber er überschreibt mir immer den Wert von Methode 1.
siehe:
Java:
public class uebung{
    final static String path = "daten.bin";
    public static void main(String[] args) {
        
        zahlInt(5);
        nameString("matze");
    }
    
    private static void nameString(String name) {
        try (RandomAccessFile datei = new RandomAccessFile(path, "rw")){
            datei.writeUTF(name);
        }
        catch (IOException e) {
            JOptionPane.showMessageDialog(null, "Beim öffnen ist ein Problem aufgetreten");
        }
    }
    
    private static void zahlInt(int zahl) {
        try(RandomAccessFile datei = new RandomAccessFile(path, "rw")){
            datei.writeInt(zahl);
        }
        catch (IOException e) {
            JOptionPane.showMessageDialog(null, "Beim öffnen ist ein Problem aufgetreten");
        }
    }
}

Am Ende möchte ich, dass die Zahl immer am Anfang steht und die Namen (sollen immer wieder neue dazu kommen) fortlaufend erstellt werden.
Die int-Zahl am Anfang soll auch veränderbar sein, z.B. aus 3 eine 4 machen.

Anschließend möchte ich wiederum mit RandomaccessFile die Zahl und die Namen wieder lesen können. Hat jemand einen Tipp für mich?
Und ja ich möchte die Klasse RandomAccessFile benutzen, weil ich das Thema vertiefen möchte und gerade gebraucht wird.

Alternativ könnte ich mir die Zahl auch als String vorstellen.
Es geht nur um das Prinzip. 1. Stelle die Zahl (auch in String) und danach die Namen.
 

Neumi5694

Top Contributor
Was deinen Fehler angeht
Vertausch mal die Aufrufe, dann wirst du sofort sehen, was du falsch gemacht hast :)
Du hast beim Schreiben vergessen, ein Offset mit anzugeben.
Du willst ja, dass am Ende angehängt wird und nicht, dass vom Anfang an geschrieben wird.
Wenn du ein neues RandomAccessFile Objekt erzeugst, dann ist der Index erst mal auf 0.
Du kannst hier als Offset jeweils die Länge der Datei angeben.

Falls du mal nachbearbeiten willst ... Du weißt, dass das nur geht, wenn alle Zahlen und Srings jeweils gleich lang sind?
Wenn du was zu langes einfügst, dann überschreibst du dir den nächsten Datensatz.

Wenn du wissen willst, wie das geht, dann fange als Übung mit einem StringArray an, in dem alle deine Daten stehen und verändere dort gezielt den Inhalt.

RandomAccessFile macht nämlich nichts anderes als das (und kann gegebenenfalls Zeichen anhängen).
Java:
var chars = "1Ab2Cd3Ef".
    chars[3]='9';
//=> der String würde jetzt so ausschauen "1Ab9Cd3Ef"
    chars[4]='G';
    chars[5]='h';
    chars[6]='i';
//=> der String würde jetzt so ausschauen "1Ab9GhiEf". Damit ist die 3 verloren.

Meiner Meinung nach ist RandomAccessFile dafür überhaupt nicht geeignet.
 
Zuletzt bearbeitet:

Jw456

Top Contributor
Da du immer ein neues RandomAccessFile machst das immer bei seek 0 anfängt .
Solltest du erst mal die länge der Datei holen in die du schreibst.
Und das seek() DateiPointer auf das ende stellen .
Beim nächsten schreiben wird dann angehangen.


Java:
File f = new File(fileName);
long fileLength = f.length();
RandomAccessFile raf = new RandomAccessFile(f, "rw");
raf.seek(fileLength);
raf.write(bytes);
raf.close();
 

matze86

Bekanntes Mitglied
OK.
Damit muss ich auch den ersten String (die Zahl) ändern können.

Dann sollte es möglich sein (eventuell mit FileReader()?) nur den ersten String auszugeben.
 

KonradN

Super-Moderator
Mitarbeiter
OK.
Damit muss ich auch den ersten String (die Zahl) ändern können.

Dann sollte es möglich sein (eventuell mit FileReader()?) nur den ersten String auszugeben.
Bitte immer genau sein! Die Zahl ist kein String! Und die wird auch nicht als String in die Datei geschrieben! Du schreibst direkt die 4 Bytes des int Werts in die Datei. Das ist ein großer Unterschied.

Was Du also auch machen könntest: Du überlegst Dir ein genaues Format - und dieses schreibst Du immer!
Also bei dir könnte es sein:
  • 4 bytes Dein int.
  • x bytes Dein Text (Das musst Du dir dann halt überlegen - was soll da rein passen?

Dann hast Du ein typisches Fileformat - denn wenn Du das als Datensatz ansiehst, dann kannst Du sagen, wie viele Bytes der Datensatz lang ist. Und dann kannst Du beliebige Datensätze lesen und auch überschreiben!

Bei einem String kannst Du dir überlegen, wie der abgespeichert werden soll. Es ist vieles denkbar:
a) Auffüllen mit Leerzeichen oder 0er- dann belegt der String immer die vollen x Bytes
b) Nach dem String kann generell ein Stopp-Kennzeichen kommen.
c) Du kannst neben dem String auch die Länge mit speichern

Das nur so als Idee.

Das kann man mit vielen diversen Ideen weiter ausbauen. Aber das wäre so ein erster kleiner Ansatz (falls Du so Datensätze haben willst)

Wenn Du wirklich nur diese zwei Daten haben willst, dann kannst Du auch sagen:
4 Bytes der int
Rest der String.
Beim Schreiben musst Du dann halt erst zum richtigen Offset und nach dem Schreiben musst Du ggf. noch die Datei verkleinern.
 

Neumi5694

Top Contributor
OK.
Damit muss ich auch den ersten String (die Zahl) ändern können.

Dann sollte es möglich sein (eventuell mit FileReader()?) nur den ersten String auszugeben.
Mit dem RandomAccessWriter kannst du einzelne Zeichen in der Datei ändern. Falls es sich bei den Zeichen um Ziffern handelt, dann ist das eben so. Es werden Methoden angeboten, ab welchem Punkt geschrieben werden soll (Offset).

Wenn sich beim Schreiben allerdings die Anzahl der Ziffern ändert, so hast du Datenverlust, dann musst du erst mal den ganzen Schmuh, der hinten dranhängt, verschieben - es sei denn - du reservierst für deine Einträge einen gewissen Platz, so wie von KonradN beschrieben.

Du solltest grundsätzlich die gesamte Datei einlesen und auch in ihrer Gesamtheit wieder schreiben. So lange die Datei kleiner ist als die Blockgröße deiner Festplatte, passiert das eh. Und einer SSD tust du garantiert keinen Gefallen, wenn du mehrere einzelne Änderungen vornimmst anstatt eines einzelnen gesammelten Schreibvorgangs.

Was den FileReader angeht ... natürlich geht das. Du kannst bestimmen, wie viel er einliest oder wann er aufhören soll.
Aber du musst dem Reader sagen, wo er stoppen soll, z.B. wenn das erste Zeichen aufscheint, as keine Ziffer ist.
Da deine Binärdatei keine Formatierungsinformationen enthält (was ist was?), musst du das selbst manuell machen, bzw. parsen.



Wenn die Datei so groß ist, dass du dir vom direkten Zugriff auf die einzelnen Bytes einen Geschwindigkeitsgewinn erwartest, dann machst du eh was falsch. Dann hast du so was wie eine DB und die schreibt man nicht manuell.

Binärdateien für Textinformationen haben schon lange ausgedient. Die waren zu DOS-Zeiten ein Thema, als Speicherplatz rar war.
Die beste Lösung wäre Serialisierung, z.B. durch JSON.
 

matze86

Bekanntes Mitglied
Also es soll so eine Art Wortliste in der Datei erstellt werden.
Ich wollte es deshalb zu Fuß machen, weil ich es lernen möchte.

Ich werde es mit gleichgroßen Strings machen, den Rest auffüllen (kann man das gleich mit der String-Instanzierung machen)?

Danach werde ich die Zeichenketten in die Datei schreiben.
 

Neumi5694

Top Contributor
Ja
für Auffüllen mit Leerzeichen
Java:
String.format("%4d, intZahl)
für Auffüllen mit Nullen
Java:
String.format("%04d, intZahl)


Um die Strings alle auf eine Länge zu bringen, musst du selbst eine Padding-Funktion schreiben. (Größe des Strings mit der Ziellänge vergleichen, dann gegebenenfalls Leerzeichen anhängen)

Tip:
Wenn (zusätzlich) noch mit Trennzeichen arbeitest, tust du dich viell leichter.
Früher hat man oft dafür Tabulatoren verwendet, csv verwendet ein Semikolon.
Pro Zahlen/Text Paar kannst du natürlich auch einen Zeilenumbruch einbauen, das macht die Datei leichter lesbar und du kannst z.B. mit einem BufferedReader (oder auch mit einem Scanner) readLine() arbeiten.
Du hast da viele Möglichkeiten. Die schlechteste Idee ist halt, komplett ohne Formatierung zu arbeiten.


Auf jeden Fall wirst du bei fixen Längen ein Problem kriegen, wenn die Länge des neuen Texts die Maximallänge überschreitet, aber das wirst du noch früh genug erleben :)
 

matze86

Bekanntes Mitglied
Ich werde jetzt mal probieren wie ich es mit den vielen Vorschlägen realisieren kann.
ich soll jedenfalls eine Wortliste in einer Datei und die Anzahl der Wörter speichern, deshalb auch die Ziffer.
 

KonradN

Super-Moderator
Mitarbeiter
Also en int belegt immer 4Byte und es macht keinen Sinn, diese als Zahl zu speichern. Den int speicherst Du als am Besten immer genau so, wie Du es bereits gemacht hast und nicht als String. (Das spart die Formatierung beim Speichern und das Parsen beim lesen!)

Lediglich beim String musst Du bei der Länge halt schauen, was Du da wie machst. Zumal Du da ja nicht die Anzahl der Zeichen sondern die Anzahl der Bytes haben willst. Und wenn du UTF-16 speicherst als Format, dann kann ein Zeichen bis zu 4 Byte lang sein! Da kommt also dann ggf. noch etwas mehr an Komplexität mit rein.
 

matze86

Bekanntes Mitglied
Oder wäre es ratsam mit einen Zeilenumbruch zu arbeiten (nach jdem wort ein Zeilenumbruch einfügen) und dann Zeile für Zeile auszugeben?
Dabei müsste die erste Zeile (die Ziffer) veränderbar sein.
 

KonradN

Super-Moderator
Mitarbeiter
Wir kennen Deine Anforderungen nicht, daher können wir Dir nicht sagen, was für Dich ratsam wäre.

RandomAccessFile wird benutzt, wenn Du in einer Datei an beliebige Stellen springen können willst um da zu lesen / zu schreiben.
Das setzt aber dann voraus, dass Du weisst, wo Du hinspringen musst.

Wenn Du sowas wie Datensätze hast, die alle die gleiche Größe haben, dann weisst Du, wo die jeweils anfangen: Bei Länge x wäre dies:
0 -> erster Datensatz (bis x-1)
x -> zweiter Datensatz (bis 2x -1)
2x -> dritter Dazensatz ...

Zeilenumbrüche sind aber doch auch nur Zeichen. Das ist etwas rein visuelles. Wenn Du hast:
zeile1
zeile2

Dann ist das nur eine Folge von Zeichen: zeile1\nzeile2

Das ist also für Dich visuell schön - da kannst Du die Zeile beliebig anpassen also z.B.
zeile1add
zeile2

Aber in einer Datei hätte sich dann die Zeile natürlich nach hinten verschoben: Du hast ja: zeile1add\nzeile2
-> zeile 2 fängt jetzt 3 Zeichen später an.



Wenn Du eh immer alle Daten liest und schreibst oder Du beim schreiben nur hinten etwas anfügen willst, dann brauchst Du kein RandomAccessFile. Dann ist es Quatsch, sich mit den Position unnötig zu beschäftigen. Diese Komplexität musst Du ja nicht manuell handhaben.
 

matze86

Bekanntes Mitglied
Wie gesagt, ich soll eine Wortliste in eine Datei schreiben und die Anzahl der Wörter. Wie ich das mache ist mir überlassen.
Anschließend muss ich in der Lage sein, die Anzahl der Wörter zu lesen und die einzelnen Wörter auszugeben - am besten noch mit Zufallsprinzip ein Wort auswählen, quasi wie eine Liste...
So ist die Fragestellung.
 

Neumi5694

Top Contributor
Wie gesagt, ich soll eine Wortliste in eine Datei schreiben und die Anzahl der Wörter. Wie ich das mache ist mir überlassen.
Anschließend muss ich in der Lage sein, die Anzahl der Wörter zu lesen und die einzelnen Wörter auszugeben - am besten noch mit Zufallsprinzip ein Wort auswählen, quasi wie eine Liste...
So ist die Fragestellung.
Also eine Zahl und eine Menge an Worten ... ok.
Ich hab das vorhin so verstanden, dass es eine gewisse Anzahl an Paaren {Zahl, Wort} gibt.


In der Aufgabe steht nicht, dass du ein einzelnes Wort schreiben/hinzufügen/lesen/ersetzen können lesen musst.
Den RandomAccessWriter kannst du schon mal vergessen, der geht komplett am Problem vorbei. Auch ist die Speicherung der Wortanzahl binär nicht wirklich praktisch, speichere die Zahl als Text ab (es sei denn, das wird explizit so verlangt).
Deine Datei enthält also als erstes einen Text mit der Anzahl der Worte, danach eine Liste von Worten.
Als erstes musst du mal die einzelnen Einträge voneinander unterscheiden können, deshalb sind Trennzeichen notwendig.
Im Grunde geht jedes Trennzeichen, aber der Zeilenumbruch ist am praktischsten, der ist a) am einfachsten zu lesen und b) gibt's dafür bereits Methoden.
In Folge beinhaltet Zeile 1 der Datei nach Ausgabe die Anzahl der Worte als lesbare Zahl, die restlichen Zeilen beinhalten die Worte.

Verwende einen PrintWriter zum Speichern, das ist am einfachsten, die println() Methode schreibt den Text + Zeilenumbruch.
Gib als erstes die Anzahl aus, dann die einzelnen Worte. Wichtig: Anders als in deinem ersten Post öffne und schließe nicht ständig die Datei, sondern schreibe die gesamte Liste auf einmal.

Auslesen per BufferedReader oder Scanner, so kannst du jede Zeile einzeln einlesen.

Kapsle da Einlesen auch gleich, schreibe eine Methode, welche die Datei öffnet, die einzelnen Zeilen in eine Liste schreibt, diese Liste als Ergebnis liefert.
Die erste Zeile dieser Liste enthält die Anzahl der Worte, parse sie mal nach Int, dann lösche die erste Zeile aus der Liste.
Nun müsste die geparste Zahl der Länge der Liste entsprechen.
Aus dieser Liste kannst du nun einzelne Worte ausgeben, ganz nach Belieben.
 
Zuletzt bearbeitet:

matze86

Bekanntes Mitglied
Sehr gut erklärt, werde ich mal versuchen so. Mit Liste meinst du ein Array oder?
Edit: wobei ich dann alles von der Date in ein Array schreiben lassen und dann auslese. Das erste Eintrag ist dann halt immer die Anzahl, die kann ich ja dann im weiteren Programm so verwenden.
 
Zuletzt bearbeitet:

Neumi5694

Top Contributor
Nein, ich meine eine Liste. Arrays sind unflexibel, für fast alle Anwendungszwecke sind Listen besser geeignet.

Aber ich denke, ihr müsst tatsächlich mit Arrays arbeiten, sonst wäre die Zahl ja nicht wichtig. Würde man eine Liste verwenden, wäre die obsolet, da die Liste in ihrer Größe änderbar ist. Es geht wohl darum, mit Arrays umgehen zu lernen und mit deren Indizes.

Bleiben wir also mal beim Array.
Dein Vorhaben (der erste Eintrag ist die Anzahl), ist technisch ok (es sind ja alles Strings), aber datentechnisch nicht (Wortliste und Beschreibung=Anzahl sind vermischt).

Bei einem Array müsstest du in der Lesemethode folgendermaßen vorgehen
1. Zahl einlesen und parsen
2. Array in der richtigen Größe erstellen.
3. Die restlichen Zeilen in das Array speichern
Sofern nicht explizit erwartet wird, dass die ausgelesene und geparste Anzahl der Worten in einer eigenen Variable gespeichert wird, musst du sie gar nicht speichern. wortListe.length() ist bereits die Anzahl.
Die Zahl in der Datei ist nur dazu da, die notwendige Größe des Arrays zu bestimmen.


Der bedeutende Unterschied, warum ich hier eine Liste favorisieren würde, wäre, dass diese flexibel ist, mit einer Länge von 0 startet und erweitert wird. Enthält die Datei z.B. mehr Worte, als in der ersten Zeile beschrieben werden, dann kannst du sie im Array nichtspeichern, es ist kein Platz dafür da. Enthält sie weniger Worte, dann hat dein Array hinten lauter null-Werte.
Bei einer Liste fügt man Elemente hinzu, dadurch erhöht sich ihr size() Wert, es gibt am Schluss keine null Werte (es sei denn, man fügt manuell welche hinzu). Man könnte die erste Zeile mit der Anzahl der Worte in dem Fall auch einfach weglassen, die Liste braucht den Wert nicht.
 
Zuletzt bearbeitet:

Neumi5694

Top Contributor
ps: Mir ist grad aufgefallen, dass ich dir was 'angekreidet' habe, was ich zu einem bestimmten Punkt auch selbst gemacht habe, nämlich die Zahl als ersten Eintrag in die Liste zu schreiben. Allerdings hätte ich die danach auch gleich wieder rausgeklöscht. Mein Vorgehen wäre gewesen:
1. Einlesen aller Rohdaten in eine Textliste, danach ist die Datei geschlossen
2. Aufbereiten der Rohdaten (erste Zeile parsen, dann rauslöschen)
3. Weiterverarbeitung ... an diesem Punkt ist die Zahl nicht mehr in der Liste, die Daten sind 'sauber'.

Mit dem Array werden die Daten bereits während des Einlesens aufbereitet, so wie oben beschrieben
 

Jw456

Top Contributor
Anschließend möchte ich wiederum mit RandomaccessFile die Zahl und die Namen wieder lesen können. Hat jemand einen Tipp für mich?
Und ja ich möchte die Klasse RandomAccessFile benutzen, weil ich das Thema vertiefen möchte und gerade gebraucht wird.
Da du es ja mit RandomAccessFile machen willst. Auch wenn die anderen Lösungen vielleicht sinnvoller sind hier eine Lösung die auf deinem Code basiert.

Java:
public class WordListe {
    final static String path = "daten.txt";
    public static void main(String[] args) {


        addWord("matze");
        addWord("Test");
        addWord("Hallo");

        System.out.println("Anzahl der Wörter "+ getCountWords());
        String[] st = createStringArray();
        System.out.println(Arrays.toString(st));

    }

    private static int  getCountWords(){
        int anzahl = 0;
        try (RandomAccessFile datei = new RandomAccessFile(path, "rw")) {
             anzahl = datei.readInt();

        } catch (IOException e) {
            JOptionPane.showMessageDialog(null, "Beim öffnen ist ein Problem aufgetreten");

        }
        return anzahl;

    }

    private static String[] createStringArray() {
        String[] words = null;
        try (RandomAccessFile datei = new RandomAccessFile(path, "rw")) {
            int anzahl = datei.readInt();
            words = new String[anzahl];
            for (int i = 0; i < anzahl; i++) {
                words[i] = datei.readUTF();
            }
        } catch (IOException e) {
            JOptionPane.showMessageDialog(null, "Beim öffnen ist ein Problem aufgetreten");

        }
        return words;
    }

    private static void addWord(String word) {
        try (RandomAccessFile datei = new RandomAccessFile(path, "rw")) {
            int anzahl;
            if (datei.length() == 0) {
                anzahl = 1;
            } else {
                anzahl = datei.readInt();
                ++anzahl;
            }
            datei.seek(0);
            datei.writeInt(anzahl);
            datei.seek(datei.length());
            datei.writeUTF(word);

        } catch (IOException e) {
            JOptionPane.showMessageDialog(null, "Beim öffnen ist ein Problem aufgetreten");
        }
    }
}
 

Jw456

Top Contributor
Add eines Array etwa so
Java:
 static void addArrayToDatei(String[] words) {
        try (RandomAccessFile datei = new RandomAccessFile(path, "rw")) {
            int anzahl;
            if (datei.length() == 0) {
                anzahl = words.length;
            } else {
                anzahl = datei.readInt();
                anzahl += words.length;
            }
            datei.seek(0);
            datei.writeInt(anzahl);
            datei.seek(datei.length());

            for (int i = 0; i < words.length; i++) {
                datei.writeUTF(words[i]);
            }
        } catch (IOException e) {
            JOptionPane.showMessageDialog(null, "Beim öffnen ist ein Problem aufgetreten");
        }
    }
 

matze86

Bekanntes Mitglied
Ich teste jetzt gerade etwas, was vielleicht umständlich ist, aber am Anfang sollte man das Coden üben vieles zu Fuss machen.

Eine Methode ("anzahl()") zählt die Zeilenumbrüche und daraus ergibt sich dann die Anzahl der Zeilen.
Danach in der Methode "namenSchreiben()" lesen ich Zeile für Zeile, jede Zeile kommt in ein Array wo ich später ein Wort hinzufügen kann.
Das sollte später erfolgen. Jetzt geht es nur darum, das ich beim vergleich der Zeilenumbrüche ('\n') trotzdem ein Zeilenumbruch mit schreibe, ich komme aber nicht drauf warum. Vielleich sieht einer von euch es mit geschulten Auge.
Hier ein Code auszug:
Java:
private static void namenSchreiben(String name) {
        String[] array = new String[anzahl()];
        int zeichen;
        String wort = "";
        int index = 0;
        boolean istZeichenkette = false;
        try (FileReader lesen = new FileReader(path)){
            zeichen = lesen.read();   
            while (zeichen != -1) {
                istZeichenkette = true;
                if ((char) zeichen != (char) '\n'){
                    wort = wort + (char) zeichen;
                }
                else {
                    System.out.println(wort);
                    array[index] = wort;
                    wort = "";
                    index++;
                }
                
                if (istZeichenkette == true) {
                    array[anzahl() -1] = wort;
                }
                
                zeichen = lesen.read();
                
            }
        }
        
        catch (IOException e) {
            JOptionPane.showMessageDialog(null, "es ist ein Fehler aufgetreten");
        }
 

Jw456

Top Contributor
Wenn du dein Array local in der Methode namenSchreiben machst. Wie willst du später darauf zugreifen und was hinzufügen.
 

KonradN

Super-Moderator
Mitarbeiter
Kannst Du das Problem etwas genauer eingrenzen? Aus Deiner Beschreibung werde ich so nicht schlau.

Was fällt bei deinem Code alles auf:

a) Evtl. hast Du ein Problem mit '\r' Zeichen. Bei Windows ist ein Zeilenumbruch nicht nur '\n' sondern ein "\r\n" - also erst ein carriage return gefolgt von einem new line Zeichen.

b) istZeichenkette ist bei Dir immer true. Das, was Du damit so machst, macht also so relativ wenig Sinn fürchte ich.

c) (char) '\n' - der cast zu char ist unnötif. '\n' ist ein char Literal.
 

matze86

Bekanntes Mitglied
b) istZeichenkette ist bei Dir immer true. Das, was Du damit so machst, macht also so relativ wenig Sinn fürchte ich.

Das stimmt, habe es jetzt ein Tab weiter raus gezogen.

Ich habe in Eclipse eine Textdatei angelegt mit mehreren Zeilen,
jede Zeile soll in das array geschrieben werden, bei der Ausgabe des Arrays zeigt mir, dass es immer ein Zeilenumbruch mit schreibt.

Wie kann man "\r\n" mit char vergleichen?
 

Jw456

Top Contributor
das sind ja zwei Chars das kannst du nicht mit einem if vergleichen.


Wenn du es im Debugger anschaust wirst du sehen das ein "\r" an dem word hängt das \n wird abgeschnitten mit deinem Code.
 

Jw456

Top Contributor
Java:
if ( zeichen !=  '\n' && zeichen != '\r') {

da musst du aber das \n auch noch etfernnen vom Stream also noch mal lesen
 
Zuletzt bearbeitet:

Jw456

Top Contributor
Einzelschritt im Debugger und dabei die Variablen beobachten. Besonders deine Variable "wort" .

Setze eine breakpoint auf dein if und dann einzelschritt
 
Zuletzt bearbeitet:

Jw456

Top Contributor
Bei dem Code in #23 kann in wort nie ein '\n' sein. Somit ist deine Beschreibung

für den Code nicht zutreffend.

Evtl. kannst Du es etwas genauer beschreiben, wo jetzt das Problem ist.
genau deshalb auch die Frage nach dem aktuellen Code.

was da am ende in dem wort ist ist das "\r" LF 0x0A dezimal 10 CR 0x0D dezimal 13.
 
Zuletzt bearbeitet:

matze86

Bekanntes Mitglied
Ich habe de Fehler gefunden, es ist kein Zeilenumbruch, sondern durch das "\r\n" wird (siehe #23) 1x in den Array ein Wort "" geschrieben, deshalb sieht es so aus, als wäre es ein Zeilenumbruch.
 

KonradN

Super-Moderator
Mitarbeiter
Du musst da halt die Logik so schreiben, dass Du bei \n das Wort hinzu fügst und bei \r das Zeichen schlicht ignorierst.

Dazu drehst Du am besten die Bedingung um - mehrere Überprüfungen auf != sind halt nicht gut.
Java:
if ( (char) zeichen == '\n') {
    // Zeilenumbruch behandeln
    // ...
} else if  ( (char) zeichen == '\r') {
    // Carriage Return behandeln - also nichts tun!
} else {
    // Zeichen hinzu fügen
    // ...
}
 

matze86

Bekanntes Mitglied
So, ich habe jetzt die Ermittlungen der Anzahl der Zeilen in einer Methode geschafft.
Zu berücksichtigen ist dabei, es dürfen keine Zeilenumbrüche mitgezählt werden, also nur vollständige Zeichenketten.
Die Methode anzahl() sieht eventuell erstmal verwirrend aus, aber sie funktioniert.

Genau so soll die Methode namenSchreiben(String) funktionieren, die soll aber, wenn eine Zeile die oben genannten Bedingungen erfüllt, die Zeilen in ein Array schreiben. Obwohl die Methode noch nicht funktioniert zeige ich sie euch mal.
Ich beiße mich gerade fest was das betrifft, weil zum Zeilenumbruch ein "\r" und ein "\n" gehört.
Deswegen arbeite ich auch mit der char-Variablen "alt", denn sie ist der Vorgänger von den aktuellen Zeichen.

Viele langjährige Programmierer schlagen bestimmt die Hände vorm Kopf was der Code betrifft, aber man kann nur dazu lernen.
Hier mein bisheriger Code:

Java:
private static int anzahl() {
        int zeilen = 0;
        int zeichen = 0;
        char alt = '\u0000';
       
        try (FileReader datei = new FileReader(path)){
            zeichen = datei.read();
            if ('\n' != (char) zeichen || (char) zeichen != '\r') {
                zeilen++;
            }
           
            while (zeichen != -1) {
                if ((char) zeichen != '\r') {
                    if (alt == '\n') {
                        if ((char) zeichen != '\n' || (char) zeichen != '\r'){
                            zeilen++;
                            //alt = (char) zeichen;
                        }                  
                    }
                }
                alt = (char) zeichen;
                zeichen = datei.read();              
            }
        }
       
        catch (IOException e) {
            JOptionPane.showMessageDialog(null, "es ist ein Fehler aufgetreten");
        }
        return zeilen;
    }
   
    private static void namenSchreiben(String name) {
        String[] array = new String[anzahl()];
        int zeichen;
        String wort = "";
        int index = 0;
        char alt = '\u0000';
       
        boolean istZeichenkette = false;
        try (FileReader lesen = new FileReader(path)){
            zeichen = lesen.read();  
            while (zeichen != -1) {
                istZeichenkette = true;
               
                if ((char) zeichen !=  '\r' && alt != '\n') {
                    if ((char) zeichen == '\n') {
                    array[index] = wort;
                    wort = "";
                    index++;
                    }
                   
                   
                    else if ((char) zeichen == '\r'){
                    }
                   
                    else {
                        wort = wort + (char) zeichen;
                    }
                }
                    alt = (char) zeichen;
                zeichen = lesen.read();
               
            }
               
            if (istZeichenkette == true) {
                if (wort.length() != 0) {
                    array[anzahl() -1] = wort;
                }
                }
                           
            }
       
        catch (IOException e) {
            JOptionPane.showMessageDialog(null, "es ist ein Fehler aufgetreten");
        }
       
        for (int i =0; i < array.length;i++) {
            if (array[i] != null)
                System.out.println(array[i]);
        }
    }
Edit: Beim Zählen der Zeilen dürften auch keine Zeilen mitgezählt werden, die nur Leerzeichen enthalten.
 

Jw456

Top Contributor
Wenn es nur für Win ist. Weißt du doch das es immer \r\n ist.
also kannst du nach einen \r testen ob noch ein \n kommt und dann weißt du das es das Zeilenende ist.
 

Jw456

Top Contributor
Die Hilfe von Konrad Post #41 willst du scheinbar nicht.
Willst an deinem Prinzip festhalten.
Dann versuche es doch mal besser so.

Java:
   boolean istZeichenkette = false;
        try (FileReader lesen = new FileReader(path)) {
            zeichen = lesen.read();
            while (zeichen != -1) {
                istZeichenkette = true;

                if ( zeichen != '\r' && zeichen != '\n') {
                    wort = wort + (char) zeichen;
                }else{
                    if ((char) zeichen == '\n') {
                        array[index] = wort;   // Ps: wenn du keine leeren Strings haben willst solltest du hier prüfen
                        wort = "";
                        index++;
                    } else if ((char) zeichen == '\r') {  // diese prüfen brauchst du eigentlich nicht
                    }
                }
                zeichen = lesen.read();

            }
 
Zuletzt bearbeitet:

matze86

Bekanntes Mitglied
Vielen dank für eure große Hilfe. Ich habe es nun so gemacht:

Eine Methode zum Zählen der Zeilen (wichtig für das spätere Array), eine weitere Methode um ein Array zu erstellen mit den Inhalt der Datei, wo jede Zeile die Nicht leer ist in ein String Element geschrieben wird. Die Anzahl der Elemente des Arrays bekomme ich von der Methode die mir die Anzahl der Zeilen zurück gibt.
In einer "schreib-Methode" kann ich die Elemente des von der "Array-Methode" des zurück gelieferten Array in die Datei schreiben (vorher löschen) und von den im Eingabefeld eingegebene String um eine Zeile erweitern.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M RandomAccessFile schreibt Sonderzeichen vor String Java Basics - Anfänger-Themen 2
N RandomAccessFile(File, String) erstellt datei?! Java Basics - Anfänger-Themen 6
B String in ein RandomAccessFile einfügen (bestimmte Position) Java Basics - Anfänger-Themen 4
N Randomaccessfile Java Basics - Anfänger-Themen 2
G Wie gebe ich einen Dateipfad in RandomAccessFile an? Java Basics - Anfänger-Themen 2
S TextArea, RandomAccessFile, Apend und andere Tricks... Java Basics - Anfänger-Themen 7
R RandomAccessFile verständnis Problem Java Basics - Anfänger-Themen 10
D RandomAccessFile Java Basics - Anfänger-Themen 2
P RandomAccessFile writeInt() und writeChar() Java Basics - Anfänger-Themen 3
L RandomAccessFile liest nicht alle Zeichen Java Basics - Anfänger-Themen 3
D Erste Schritte RandomAccessFile "Leerzeichen" löschen Java Basics - Anfänger-Themen 6
F Kann RandomAccessFile Zip Datei lesen? Java Basics - Anfänger-Themen 14
B Klassen RandomAccessFile Java Basics - Anfänger-Themen 7
B Collections RandomAccessfile & Linkedlist Java Basics - Anfänger-Themen 4
M Frage zur Klasse RandomAccessFile Java Basics - Anfänger-Themen 8
cosmic Frage zu der RandomAccessFile Klasse Java Basics - Anfänger-Themen 6
K RandomAccessFile Java Basics - Anfänger-Themen 4
T RandomAccessFile - Wie schreibe ich etwas in eine txt Datei? Java Basics - Anfänger-Themen 5
C RandomAccessFile vs. Streams Java Basics - Anfänger-Themen 5
D text dateien mit RandomAccessFile manipulieren Java Basics - Anfänger-Themen 6
T RandomAccessFile und der Dateipfad Java Basics - Anfänger-Themen 2
J RandomAccessFile löschen Java Basics - Anfänger-Themen 2
M RandomAccessFile Java Basics - Anfänger-Themen 3
G RandomAccessFile, FileChannel, MappedByteBuffer Java Basics - Anfänger-Themen 12
P Datei mit RandomAccessFile einlesen Java Basics - Anfänger-Themen 14
R RandomAccessFile mit anderen Streams verbinden Java Basics - Anfänger-Themen 5
J File, RandomAccessFile File wird größer Java Basics - Anfänger-Themen 8
J RandomAccessFile schreibt falsch Java Basics - Anfänger-Themen 2
G RandomAccessFile Java Basics - Anfänger-Themen 20
R RandomAccessFile Java Basics - Anfänger-Themen 4
R RandomAccessFile und ObjectoutputStream Java Basics - Anfänger-Themen 2
T RandomAccessFile erzeugt seltsame Zeichen Java Basics - Anfänger-Themen 2
P RandomAccessFile Java Basics - Anfänger-Themen 2
L RandomAccessFile und readChar readByte Java Basics - Anfänger-Themen 2
D konvertierungsprobleme bei RandomAccessFile Java Basics - Anfänger-Themen 4
L RandomAccessFile - Prob Java Basics - Anfänger-Themen 4
B RandomAccessFile Java Basics - Anfänger-Themen 12
M RandomAccessFile liest nur jeden zweiten Wert aus! Java Basics - Anfänger-Themen 8
G RandomAccessFile Java Basics - Anfänger-Themen 2
O RandomAccessFile komisch zeichen Java Basics - Anfänger-Themen 7
A RandomAccessFile Java Basics - Anfänger-Themen 7
krgewb String mit Datumsangabe in Long umwandeln Java Basics - Anfänger-Themen 2
D String Groß/Kleinschreibung Ignorieren Java Basics - Anfänger-Themen 4
D Map<String, Integer> sortieren und der reinfolge nach die Glieder abfragen Java Basics - Anfänger-Themen 3
J Ähnlichen String in Liste finden Java Basics - Anfänger-Themen 6
Kartoffel_1 String transformation Java Basics - Anfänger-Themen 7
H String-Operation replace() - Zeichenkette verdoppeln Java Basics - Anfänger-Themen 2
K String analysieren Java Basics - Anfänger-Themen 27
Beowend String zu Date parsen Java Basics - Anfänger-Themen 1
Beowend String auf Satzzeichen überprüfen? Java Basics - Anfänger-Themen 6
H Liste nach String-Länge sortieren Java Basics - Anfänger-Themen 1
String in ArrayList umwandeln Java Basics - Anfänger-Themen 1
I Sass Compiler und String erhalten? Java Basics - Anfänger-Themen 7
Avalon String in Double bzw. Währung konvertieren Java Basics - Anfänger-Themen 6
T Methode akzeptiert String nicht Java Basics - Anfänger-Themen 18
F Arraylist<String>Ein Wort pro Zeile Java Basics - Anfänger-Themen 6
J Schlüsselworte Prüfen, ob ein bestimmtes, ganzes Wort in einem String enthalten ist. Java Basics - Anfänger-Themen 6
N String überprüfen Java Basics - Anfänger-Themen 3
E String zerlegen aus args Java Basics - Anfänger-Themen 1
M Long-Typ in String-Änderung führt zu keinem Ergebnis bei großer Zahl Java Basics - Anfänger-Themen 11
Ostkreuz String Exception Java Basics - Anfänger-Themen 8
W Items löschen aus String Array vom Custom Base Adapter Java Basics - Anfänger-Themen 2
MoxMorris Wie macht man String[] = String[] aus einer anderer Methode? Java Basics - Anfänger-Themen 18
J String Filter Java Basics - Anfänger-Themen 5
S String Array Buchstaben um einen gewissen Wert verschieben Java Basics - Anfänger-Themen 4
R Größter zusammenhängender Block gleicher Zeichen im String Java Basics - Anfänger-Themen 1
XWing Randomizer mit einem String Java Basics - Anfänger-Themen 2
D 2D Char Array into String Java Basics - Anfänger-Themen 2
H Cast von Float nach String klappt nicht Java Basics - Anfänger-Themen 12
I Zerlegen von String Java Basics - Anfänger-Themen 3
B Beliebiger String gegeben Suche Datum in String Java Basics - Anfänger-Themen 6
I String Java Basics - Anfänger-Themen 4
I API - zurückgegebener JSON String lesen und in Entity konvertieren Java Basics - Anfänger-Themen 2
H Zu langen String aufteilen - bequeme Methode? Java Basics - Anfänger-Themen 14
W String einer Textdatei in einzelne Stringobjekte pro Zeile aufteilen Java Basics - Anfänger-Themen 14
belana wie am besten 2D Array von String to Integer Java Basics - Anfänger-Themen 18
J Java To String Methode, Array mit For-Schleife Java Basics - Anfänger-Themen 2
M Kommandozeilenparamter als EINEN String werten Java Basics - Anfänger-Themen 5
M Prüfen on eine Zahl im String enthalten ist Java Basics - Anfänger-Themen 3
Distanz zwischen zwei Zeichenfolgen in einem String bestimmen Java Basics - Anfänger-Themen 5
Substring in einem String finden Java Basics - Anfänger-Themen 13
BeginnerJava String mit vorgegebener Länge und Buchstaben erzeugen/ mit Leerstellen Java Basics - Anfänger-Themen 8
I Eindeutiger String mit maximaler Anzahl an Zeichen Java Basics - Anfänger-Themen 11
H Interface Wieso "List<String> list = new ArrayList<>[…]" Java Basics - Anfänger-Themen 4
JavaBeginner22 Integer in String umwandeln Java Basics - Anfänger-Themen 7
HolyFUT JSON String in Java Object schreiben - Anführungszeichen rauskriegen? Java Basics - Anfänger-Themen 17
Fodoboo131 RegEx- Umwandlung von String in ausführbares Objekt/ Befehl Java Basics - Anfänger-Themen 9
HolyFUT Input/Output Leerzeichen aus String entfernen - klappt nicht! Java Basics - Anfänger-Themen 13
viktor1 Methoden Methode schreiben static void readText (String filename) {...} zu WordHistogramSample.java Java Basics - Anfänger-Themen 13
ravenz Schleife mit for über String Array „zahlen“und prüfen ob Wert „a“ oder „b“ oder „c“ entspricht (mittels || ) Java Basics - Anfänger-Themen 4
G Position einer unbekannten 3-stelligen-Zahl in einem String finden Java Basics - Anfänger-Themen 15
T String Array Fehler beim Index Java Basics - Anfänger-Themen 3
H Erste Schritte Nach einer Zahl n soll n Mal der String untereinander ausgegeben werden Java Basics - Anfänger-Themen 3
X Datentypen String.equals funktioniert nicht Java Basics - Anfänger-Themen 5
Alen123 String wiederholen mit Schleifen Java Basics - Anfänger-Themen 1
A String split funktioniert nicht, wenn mehr als 1 Ziffer vor dem Zeichen steht nach dem er trennen soll? Java Basics - Anfänger-Themen 4
T String splitten Java Basics - Anfänger-Themen 3
sserio Schwimmen als Spiel. Problem mit to String/ generate a card Java Basics - Anfänger-Themen 4
J Datentypen String in File konvertieren funktioniert nicht Java Basics - Anfänger-Themen 4
T Platzhalter in String? Java Basics - Anfänger-Themen 14

Ähnliche Java Themen

Neue Themen


Oben