dumme fragen zu ... dateien?



  • shisha schrieb:

    was bedeutet Pufferung überhaupt?

    Daß die Datei in größeren Einheiten als 1 Byte beschrieben oder ausgelesen wird.

    shisha schrieb:

    Ist RandomAccessFile gepuffert?

    Nein!

    shisha schrieb:

    ich hab da Code-Stücke gefunden:

    BuffererReader in = new BufferedReader(new FileInputReader(File irgendwas))

    wobei erklärt steht dass das die Geschwindigkeit enorm erhöht.

    nun die Frage. Ist FileInputStream auch einfach durch RandomAccessFile zu erstetzen? oder brauch ich das gar nicht?

    Wofür brauchst du's denn?



  • es geht mir hier nicht um das was ich brauche.
    Im Grunde reicht es mir erstmal überhaupt dateien zu schreiben oder zu lesen.

    mit hilfe von randomaccessfile kann ich auch super in meinen dateien herumhüpfen, aber mir gehts vor allem darum, das ganze mal zu verstehen und irgendwann mal selbst zu wissen, was ich wann verwende...

    wenn random jetzt nicht gepuffert ist kann ich dann daruas einen BufferedWriter machen?



  • Ich hab da auch ein Problem mit Ausgabedateien:

    Ich habe eine Log-Funktion, die einen DataOutputStream verwendet, um Text in eine Datei zu schreiben. Irgendwie finde ich aber keine passende Funktion, mit der ich einen String abspeichern kann.

    Es gibt keine writeString Funktion, sondern nur eine writeUTF. Wenn ich die benutze, kann ich die .txt nicht mehr mit Notepad öffnen. In Wordpad kann ich die Datei zwar öffnen, aber vor jeder Zeile sind zwei Sonderzeichen (meistens Kästen, aber auch willkürlich andere). Wie kann ich das verhindern?



  • snOOfy schrieb:

    Ich hab da auch ein Problem mit Ausgabedateien:

    Ich habe eine Log-Funktion, die einen DataOutputStream verwendet, um Text in eine Datei zu schreiben. Irgendwie finde ich aber keine passende Funktion, mit der ich einen String abspeichern kann.

    Es gibt keine writeString Funktion, sondern nur eine writeUTF. Wenn ich die benutze, kann ich die .txt nicht mehr mit Notepad öffnen. In Wordpad kann ich die Datei zwar öffnen, aber vor jeder Zeile sind zwei Sonderzeichen (meistens Kästen, aber auch willkürlich andere). Wie kann ich das verhindern?

    Gemäß Dokumentation schreibt writeUTF den String als modifiziertes UTF-8-Format mit zwei vorgestellten Bytes, in denen die Länge der Zeichenkette angegeben ist.

    DataOutputStream eignet sich hervorragend für das Schreiben von einfachen binären Datenströmen, deren Inhalt man auch wieder mit DataInputStream lesen möchte. Für Textdateien, die auch mit einem normalen Editor geöffnet werden sollen, ist die Klasse kaum geeignet.

    Verwende die Writer-Klassen (z.B. BufferedWriter)!



  • Verwende die Writer-Klassen (z.B. BufferedWriter)!

    Das wollte ich erst, aber dann habe ich gesehen, dass man da zum speichern eine close()-Anweisung benutzen muss. Wenn mein Programm irgendwo abstürzt, soll die Logdatei aber trotzdem gespeichert werden. Lässt sich das machen?



  • snOOfy schrieb:

    Das wollte ich erst, aber dann habe ich gesehen, dass man da zum speichern eine close()-Anweisung benutzen muss. Wenn mein Programm irgendwo abstürzt, soll die Logdatei aber trotzdem gespeichert werden. Lässt sich das machen?

    Da gibt's die Methode flush(). Damit sollten die Streamdaten geschrieben werden. Die Methode kannst du aufrufen, wenn ein Eintrag zum Protokoll geschrieben wurde.



  • ist randomaccessfile performant genug um es immer einzusetzen oder sollte cih in bestimmten fällen (welche?) andere möglichkeiten in betracht ziehen?



  • RandomAccessFile kann schon performant sein, sogar performanter als irgendwelche BufferedReader bzw. BufferedInputStreams aber nur wenn du tatsächlich größere Blöcke am Stück liest bzw. schreibst. Mit größer ist sowas ab 500-1000 Byte Länge gemeint. Aber selbst wenn du nur kleinere Stücke lesen willst, kann RandomAccessFile die richtige Wahl sein, nämlich dann wenn du tatsächlich andauernd im File hin- und herspringen musst, das File zu groß ist um es einmal komplett in den Speicher zu laden und es eher unwahrscheinlich ist, dass du hinter einem Lesezugriff gleich als nächstes sofort nochmal weiterlesen willst.

    Nur bei sequentiellen Zugriffen, bei denen du die ganze Datei jeweils Zeichen für Zeichen in einer Schleife nacheinander lesen willst haben die Buffered... Klassen erhebliche Performance Vorteile. Das liegt aber vor allem daran, dass die Methode zum Lesen einzelner Zeichen an den meisten Streams sehr ineffizent implementiert ist (geerbt von InputStream). Ein Buffering macht auch das Betreibssystem schon, das hast du also auch beim simplen FileInputStream oder beim RandomAccessFile immer mit dabei. Die Buffered... Klassen machen nix anderes als jeweils immer gleich größere Blöcke am Stück aus dem darunter liegenden FileInputStream in ein internes Array zu lesen und aus diesem dann die Leseanfragen zu beantworten. Wenn der intern gepufferte Block leer ist wird automatisch ein neuer gelesen. Im Prinzip ist das aber überflüssiger Overhead wenn du deine Daten sowieso in ein größeres Array einlesen willst. Die (Buffered-)Reader zwingen dir außerdem intern immer einen ByteToCharConverter auf, der sich je nach Betreibssystem bzw. eingestellter Benutzersprache ändert und dir damit potentiell deine Daten korrumpieren kann sobald ein Benutzer mal keinen westeuropäischen Zeichensatz (ISO 8859-1) eingestellt hat, dessen Zeichen "zufällig" mit den ersten 256 Zeichen von Unicode übereinstimmen. Deshalb solltest bei der Verwendung von Readern/Writern den Zeichensatz immer explizit angeben, es sei denn, du willt mal tatsächlich reine Textdaten aus dem beim Benutzer voreingestllten 8-Bit Zeichensatz nach Unicode convertiert haben, was selten wirklich sinnvoll ist. Speziell bei Binärdaten ist es am Besten auf die Reader/Writer ganz zu verzichteen und bei den Input- und OutputStreams zu bleiben, zumal die auch noch performater sind.

    Wenn du wirklich Performancekritische Sachen mit Random Access Files machen willst eignen sich natürlich auch die diversen FileBuffer aus dem newio Package. Damit kannst du dann vor allem auch Memory Mapped Files verwenden. Der Zugriff ist zwar etwas umständlicher und nicht mehr so schön verkettbar wie mit den Streams aber die Performance kann sich damit nochmal deutlich steigern lassen, besonders wenn du auch noch abwechselnd in das gleiche File an verschiedenen Stellen schreiben und lesen willst (wie z.B. bei einer Datenbank-Implementierung).

    Um wirklich ein Gefühl dafür zu bekommen musst aber mal ein bisschen mit den diversen Varianten rumspielen und selber messen wie perfromant es ist. Alle Varianten haben ihre Vor- und Nachteile und können je nach Anwendungsfall geeigneter oder ungeeigneter sein.



  • nochmals zu dem thema,

    ich habe jetzt etwas mit allem herumgespielt und es zumindest geschafft einfache textdateien zu erzeugen.
    Hier nun die Frage:

    Was ist der UNterschied zwischen
    FileOutpuStream und FileWriter ?



  • shisha schrieb:

    Was ist der UNterschied zwischen
    FileOutpuStream und FileWriter ?

    Die OutputStream-Klassen schreiben Bits und Bytes in Rohform. Man kann sie beispielsweise auch verwenden, um eine Bitmap-Datei (bmp) oder andere Binärdateien zu generieren (sofern man den Aufbau kennt) - auch Textdateien fallen darunter.

    Die Writer-Klassen hingegen sind spezialisiert auf das Schreiben von Textdaten und nehmen dir schonmal die Arbeit mit den vielen unterschiedlichen Zeichencodes ab (ISO-8859-1, UTF-8, usw.).



  • mal wieder bin ich auf etwas gestossen das mir etwas kopfzerbrechen bereitet und zwar:

    datainputstreams

    wo kann ich diese einordnen? wofür sind sie gedacht? <bevor ich sie schamlos missbrauche>

    Interessant ist der Zusammenhang DataInputStream <-> FileInputStream <-> FileReader

    Hintergrund ist:

    ich möchte die verschiedenen Varianten der IO kennenlernen und vlt ein kleines Programm schreiben um mp3 auszulesen



  • lies lieber was mit nem einfacheren format als mp3 aus.
    das einzige was bei mp3 noch halbwegs einfach auszulesen geht, ist ein evtl. vorhandener ID3V1 tag 😉
    (also das lesen von bytes aus mp3 files ist natürlich einfach - dann mit diesen bytes was sinnvolles anzufangen ist das schwierige)



  • ich möchte einen string in bytes umwandeln, eig sollte das doch per
    string.getbytes() klappen,
    ich möchte nun aber sicher gehn dass das erzeugte array eine exakte größe hat

    wie kann ich das erreichen?
    es geht vor allem darum wenn ich einen zu kleinen string habe



  • warum willst du die größe des arrays überprüfen, und womit willst du die dann vergleichen :?



  • ich möchte an den mp3 tags herumspielen
    und da ist die länge eines tags fest vorgegeben, also muss ich mich da anpassen

    nebenbei:wie kann ich in eine textdatei einen zeilenumbruch schreiben?
    out.write(10) klappt nicht



  • \n

    😕



  • ja das war nichzt meine schuld der editor von microsoft hat die leerzeichen einfach nicht angezeigt^^

    aber das andere problem hab ich noch:

    string in byte festgegebener größe zu verwandeln



  • ich hab jetz ein wenig herumgespielt und hier ist das was mir sorgen bereitet:

    String s = "Ich du er sie es";
    		String small = "kleiner";
    		String result;
    		byte[] b , tmp;
    
    		//System.out.println(s.length());
    
    		try
    		{
    			tmp = small.getBytes("US-ASCII");
    			b = s.getBytes("US-ASCII");
    			System.out.println(b.length);
    			b = small.getBytes("US-ASCII");
    			System.out.println(b.length);
    
    			result = new String(b);
    			System.out.println(result);
    			result = new String(tmp);
    			System.out.println(result);
    
    			System.out.println(b);
    			System.out.println(b.length);
    			System.out.println(tmp);
    			System.out.println(tmp.length);
    		}
    

    b und tmp beinhalten am Schluss den selben String und haben die selbe Länge.
    Aber was ist mit dem Rest von String s in b ?
    b und tmp unterscheiden sich anscheinend doch.

    ich kann leider nicht viel damit anfangen und bitte um aufklärung



  • nun bin ich vollends verwirrt:

    package bt;
    
    import java.io.*;
    
    public class Bytes 
    {
    	public static void main(String[] args)
    	{
    		byte[] b1, b2;
    		String big = "langerstring";
    		String small = "kleiner";
    
    		try
    		{
    			b1 = small.getBytes("US-ASCII");
    			b2 = small.getBytes("US-ASCII");
    
    			System.out.println(b1);
    			System.out.println(b2);
    		}
    		catch(Exception e){}
    
    	}
    }
    

    führt zu:

    [B@addbf1
    [B@42e816

    wieso erzeugt das programm 2 verschiedene ausgaben?
    ich nehme doch den selben string auf die selbe art und weise ran...




Anmelden zum Antworten