Read and Write File

Micka

Micka

Fortgeschrittenes Mitglied
1
Hallo,
ich bin dabei eine eigene App zu entwickeln in der ich Daten in eine Datei schreiben möchte. Das ganze muss möglichst schnell von statten gehen da viele Daten pro Sekunde weggeschrieben werden müssen.

Ich habe bereits herausgefunden das es schneller ist ein Bytearray wegzuschreiben als z.B: ein BitString. Das Bytearray hat leider eine variable Länge.

Nun habe ich das Problem, ich weiß nicht wie ich die Datei wieder auslesen kann, so dass ich bytearray für bytearray die Daten erhalte. Ohne Trennzeichen ist das wegeschreiben am aller schnellsten, aber ich denke es ist notwendig die einzelnen Arrays irgendwie voneinander zu trennen. Deshalb habe ich nach jedem Array noch "\n\n".getBytes() in die Datei schreiben lassen. Aber wie lese ich das ganze jetzt so wieder aus das ich saubere bytearrays erhalte?

Im folgenden noch kurz mein Code mit dem ich das ganze weggeschrieben habe:
Code:
//bigData ist ein zweidimensionales  byte[]
String state,zeile, header;
File file, Root, Dir;
FileOutputStream fos;
state = Environment.getExternalStorageState();
if(Environment.MEDIA_MOUNTED.equals(state))
{
    Root = Environment.getExternalStorageDirectory();
    Dir = new File(Root.getAbsolutePath()+"/LudvikAppFiles");
    if(!Dir.exists())
    {
        Dir.mkdir();
    }
    file = new File(Dir, filename + ".txt");
    fos = null;
    try
    {
        fos = new FileOutputStream(file);
        for(byte[] mData: bigData)
        {
            fos.write(mData);
            fos.write("\n\n".getBytes());
         }
         fos.close
    } catch (FileNotFoundException e)
    {
        e.printStackTrace();
    }
}else
{
    //ERROR
}
 
@Micka
Als erstes benutze kein zweidimensionales Array, die Dinger sind wirklich langsam, und verbrauchen sehr viel Speicher.
(Und zwar immer. Array sind eigentlich fast immer die schlechteste Lösung.)

Wenn die Daten als Chars in der App vorliegen, nimm einen FileWriter. Das ist schneller.

Insgesamt sind Schreib- und Lese-Vorgänge in der internen/externen Speicher nicht unbedingt die schnellste Lösung. Sinnvoller wäre eine Methode, die nur in Notfälle die Daten in den Speicher schreibt und liest.

Dein Code hat ein Speicherleck. Unter Java muss ein Stream auch geschlossen werden, wenn ein Fehler auftritt.
D.h. im Catch-Block muss der der Befehl fos.close() aufgerufen werden.

Code:
catch(FileNotFoundException e) {
    Log.e("Stream","Error Stream",e);
    try {
        if (fos != null)
           fos.close();
    }catch (Exception e) {
        Log.e("Stream","Error Stream",e);
    }
}
[doublepost=1455406245,1455404896][/doublepost]Nachtrag:

Versuche zu erst sauberen Code zu Programmiere. Meist muss man dann gar nicht den Code optimieren, weil er schon schnell genug ist. Am besten benutzt du einfache Lösungen (KISS).
 
markus.tullius schrieb:
Dein Code hat ein Speicherleck. Unter Java muss ein Stream auch geschlossen werden, wenn ein Fehler auftritt.
D.h. im Catch-Block muss der der Befehl fos.close() aufgerufen werden.
.

Try-with-Resources würde sich hier dann besser anbieten. Unter Java kann man aber nie 100% sicher sein dass dann nicht trotzdem etwas schief geht und der Stream offen bleibt.
 
Nachtrag 2:

Für den Weg zurück braucht man ein FileInputStream.
FileInputStream | Android Developers
[doublepost=1455407387,1455406532][/doublepost]@Jaiel
Kommt auf das gleiche hinaus. Ist nur eine schönere Formulierung (Außerdem gibt es immer noch Geräte, die mit Java 6 laufen).
Schöner wäre natürlich, wenn man Dependency Injection arbeitet, dann übernimmt das im besten Fall das Framework den gesamten foo bar.
https://de.wikipedia.org/wiki/Dependency_Injection
[doublepost=1455407608][/doublepost]Hier fehlen mir Zeiger, mit denn könnte man den Stream direkt in die richtigen Adressen verfrachten. ;)
 
  • Danke
Reaktionen: Micka
Die Daten werden per Bluetooth empfangen und liegen daher als bytes vor. Eine Nachricht besteht aus maximal 15bytes und es kommen ca 10 000 pro Sekunde rein.
Ich habs zunächst mit Datenbanken versucht, domumentorientiert, objektorientiert und relational. Aber während des Empfangs sind die leider zu langsam. (1400ms für 10000 Nachrichten, aber sehr Hardwareabhängig) Nun dachte ich ne Datei benötigt weniger CPU Leistung. Fürs spätere betrachten ists schöner das ganze als Hex Werte anzusehen. Aber die Konvertierung in Hex Strings ist ziemlich zeitaufwendig. Deswegen hab ich die einzelnen Arrays zu einer Nachricht in ein Array gepackt. Von Datenbanken kenne ich die Methode des Bulks um die Performance zu optimieren. Deshalb hab ich mit nen 2 dimensionalen Array gearbeitet.

Das schließen des Streams im Catch Block ist ja kein Problem. Aber wie erkenne ich wo das eine Array endet und das nächste anfängt?
[doublepost=1455447600,1455443359][/doublepost]Habe es gerade mal mit nem FIlewriter probiert, aber der ist langsamer oder gleich schnell als wenn ich den FileOutPutstream verwende mit der Methode String.getBytes(). Alleine das konvertieren der bytes in einen String benötigt zu viel Zeit. Für die Diagnose Ausgabe kann man die Zeit investieren, aber während des Datenempfangs müssen die Daten erstmal nur schnell gespeichert werden. Bleibt die Frage wie ich Anfang und Ende der arrays erkenne und das gescheit auslese
 

Ähnliche Themen

M
  • myoggradio
Antworten
1
Aufrufe
776
myoggradio
M
B
Antworten
6
Aufrufe
1.049
jogimuc
J
5
Antworten
5
Aufrufe
1.204
jogimuc
J
Zurück
Oben Unten