C++ Datei als Short int array einlesen.

OP #4368832
Lesenswert?

Hi,

ich habe eine Datei mit Farbinformationen als Bin mit theoretisch immer 
aufeinander folgenden 2Bytes als "unsigned short int".

Im moment lese ich mit gseek immer 2 Bytes ein, konvertiere die 2Bytes 
zu einem Short Int und schiebe die nacheinander wie in der Datei 
sortiert in ein Array.

Das einlesen dauert mit 2MB von der SD-Card eben mal 30-60Sekunden.

Zuerst dachte ich das es am besten ist die Ganze Datei als char Array 
mit großem Buffer einzulesen und dann das casten zu starten.

Dann habe ich ähnliches mit float und Vector gesehen wo das irgendwie in 
einem Rutsch geht, nur verstehe ich die ganze Geschichte dahinter nicht.

Andere Idee,vielleicht liegen die Bytes schon richtig und können sogar 
direkt gemapped werden.

Was wäre denn jetzt die Sinnvollste Methode?
#4368838
Lesenswert?

Philipp K. schrieb:
> Im moment lese ich mit gseek immer 2 Bytes ein

Meinst du seekg? Damit kann man gar nichts einlesen sondern nur die 
Position setzen wo man als nächstes lesen will. Wenn man aber alles 
nacheinander lesen will ist das überhaupt gar nicht nötig. Du kannst 
einfach mit read 
(http://en.cppreference.com/w/cpp/io/basic_istream/read) immer 2 Bytes 
laden und die Position wird automatisch 2 Bytes weiter gesetzt.

Ob du erst alles einließt und dann konvertierst oder beim Einlesen 
konvertierst sollte ziemlich egal sein. Zeig mal deinen Code.
OP #4368845
Lesenswert?

Ah sorry, bin da noch nicht solang mit c++ das ich alles im Kopf habe, 
seekg klar, wenn man english kann leuchtets ein also ich meinte Read.

Verstanden habe ich die Sache schon soweit das ich den Copy&Paste Code 
schon für mich angepasst habe. Der war vorher um ein BMP einzulesen..

Mir geht es nur darum das Read durch einen kleinen Buffer im folgenden 
Code zu langsam sein müsste.
1
   file.seekg (0, file.end);
2
        size = file.tellg();
3
        matrix= new(unsigned short int[size/2]);
4
        sof=0;
5
        int counter=0;
6
        while(sof<size)
7
        {
8
            file.seekg(sof,ios::beg);
9
            file.read(tmp,2);
10
            tx = BinToNum(tmp,2);
11
            matrix[counter] = tx;
12
            sof+=2;
13
            counter++;
14
        }

EDIT: Wodran ich gerade hänge:
1
vector<unsigned short int> buffer(size);
2
if (file.read(buffer.data(), size))
3
{}
Gast #4368866
Lesenswert?

Es sollte etwas in der folgenden Art gehen:
(nicht getestet, nur so als Idee, seekg: nie benutzt...)

        file.seekg (0, file.end);
        size = file.tellg();
        matrix= new(unsigned short int[size/2]);
        file.seekg(0,file.begin);
        file.read(matrix,(size/2) * sizeof(unsigned short int));

Vielleicht hast du aber dann noch Endian-Problem...
#4368935
Lesenswert?

Philipp K. schrieb:
> Ah sorry, bin da noch nicht solang mit c++ das ich alles im Kopf habe,
> seekg klar, wenn man english kann leuchtets ein also ich meinte Read.
>
> Verstanden habe ich die Sache schon soweit das ich den Copy&Paste Code
> schon für mich angepasst habe. Der war vorher um ein BMP einzulesen..
>
> Mir geht es nur darum das Read durch einen kleinen Buffer im folgenden
> Code zu langsam sein müsste.
>    file.seekg (0, file.end);
>         size = file.tellg();
>         matrix= new(unsigned short int[size/2]);

new ist keine Funktion, also lass die Klammern weg:

         matrix= new unsigned short int[size/2];

>         sof=0;
>         int counter=0;
>         while(sof<size)
>         {
>             file.seekg(sof,ios::beg);
>             file.read(tmp,2);
>             tx = BinToNum(tmp,2);
>             matrix[counter] = tx;
>             sof+=2;
>             counter++;
>         }

Das läßt sich evtl. schon deutlich beschleundigen, wenn du den seekg 
wegmachst. Den brauchst du sowieso nicht.
Persönliche Seite #4368970
Lesenswert?

Wenn die Bytes in der Datei in der korrekten Reihenfolge abgelegt sind, 
dann geht auch so etwas:
1
file.seekg(0, file.end);
2
size = file.tellg();
3
matrix = new uint16_t[size / 2];
4

5
file.seekg(sof,ios::beg);
6
file.read((uint8_t *) matrix, size);

Das geht nur dann schief, wenn aus Alignmentgründen die 16-Bit-Werte 
nicht ohne Lücken im Speicher abgelegt werden können, was manche 
32-Bit-Architektur möglicherweise machen könnte.

Das lässt sich mit dem sizeof-Operator prüfen, wie groß ist ein Array 
aus zwei uint16_t? Doppelt so groß wie ein einzelner uint16_t?
Persönliche Seite #4369062
Lesenswert?

Klaus W. schrieb:
> als ob es mit "memory mapped file"

Kommt ganz drauf an, was für ein Betriebssystem und was für eine 
Hardware hier verwendet wird. Das hat der Threadstarter für sich 
behalten, auch wenn man vermuten kann, daß es hier um ein Programm auf 
einem PC geht.

Allerdings: Warum sollte ein "memory mapped file" hier schneller sein 
als ein einziger Aufruf von read()? Was glaubst Du, macht ein "memory 
mapped file" anderes?
#4369068
Lesenswert?

so wie ich das verstanden habe, geht es nicht darum, einmal 2 Byte 
anzufassen, sondern oft hintereinander (sonst würde er die Lesezeiten ja 
gar nicht merken).
Und das geht nach meiner Erfahrung mit mmap meist dramatisch schneller.

Hatten wir nicht schon mal diese Diskussion?

(Ein AVR wird es nicht sein, wenn er mit seekg hantiert.)
#4369076
Lesenswert?

Rufus Τ. F. schrieb:
> Allerdings: Warum sollte ein "memory mapped file" hier schneller sein
> als ein einziger Aufruf von read()? Was glaubst Du, macht ein "memory
> mapped file" anderes?

Wenn der Inhalt einer Datei bzw. eine Seite davon erstmal in den 
Speicher eingeblendet ist, geht der Zugriff über einen Pointer darauf 
wesentlich schneller, einfach weil nichts kopiert werden muß und 
keinerlei Bibliotheksfunktionen bemüht werden.
OP #4369166
Lesenswert?

Danke für die vielen Tips :)

Also da ist kein Geheimnis denn es ist ein RPi und die Datei liegt auf 
der sdcard vom System.

Die Bin Datei beinhaltet ganze Font Zeichensätze die ich selbst gemalt 
habe um Headless in einen SPI-Buffer zu schreiben.. das funktioniert 
schonmal mit 25fps und da verschiebe ich den ganzen matrix array mit for 
Schleifen bei jedem einzelbild. Also im ganzen dauert mir das Laden der 
Datei zu lang beim Debuggen, wenn ich die Daten direkt ins Headerfile 
schmeisse mault der RPi beim Kompilieren Speicher voll. Ich finde es 
trotzdem interessant den richtigen Ansatz zu finden.

Hier mal mein wie soll ich sagen.. schauen obs klappt dann mach ichs 
schick  Workaround File:

http://bit.do/philipp_k

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren