Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » Problem beim Einlesen einer Datei

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
28.08.2005, 20:35 Uhr
~Datei-Frage
Gast


Hallo,

Ich möchte gerne eine Datei einlesen in einen String. Dabei gehe ich so vor, dass ich zuerst gucke ob die Datei größer als 256 Byte ist und dann immer 256 Byte aufeinmal einlese mit fread, damit es schneller geht. Wenn nur noch weniger als 256 Byte übrig sind, wird jedes Byte einzeln eingelesen bis zum Schluss. Das Problem ist, dass das Einlesen der 256-Byte-Abschnitte ohne Probleme geht, aber wenn dann am Ende der Datei Byte für Byte einlesen wird steht nur Müll im Buffer. Hier der Code:


C++:
string Daten1 = "";
    try
    {
        FILE * pInfoFile2 = fopen (FileName.c_str(),"rb");
        char* Daten2 = new char[2]; // 1 Byte + \0
        char* Daten3 = new char[257]; //256 Byte + \0
        int FileSize;
        FileSize = _filelength(_fileno(pInfoFile2));
        if(!pInfoFile2 == NULL)
        {
            if (_filelength(_fileno(pInfoFile2)) > 256) // Ist die Datei größer als 256 Byte?
            {
                while(Daten1.length() < (_filelength(_fileno(pInfoFile2)) - 256)) //Dann Einlesen bis noch 256 Byte übrig sind
                {
                    Sleep(3);
                    fread(Daten3,1,256,pInfoFile2); //256 Byte aufeinmal einlesen
                    Daten3[256] = '\0'; // Null-Terminiert
                    Daten1 += (string)Daten3; //Daten in den String
                }
            }
            while(Daten1.length() < (_filelength(_fileno(pInfoFile2)))) // Den Rest der Datei einlesen
            {
                Sleep(3);
                fread(Daten2,1,1,pInfoFile2); //Jetzt immer nur 1 Byte lesen
                int i = GetLastError();
                Daten2[1] = '\0'; //Null-Terminiert
                Daten1 += (string)Daten2; // Und Daten in den String
            }
            fclose(pInfoFile2);
        }
    }
    catch(...)
    {
    }


Beim Byteweise einlesen steht immer nur das Zeichen -51 im Buffer. Weiss jemand was da falsch ist?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
29.08.2005, 10:27 Uhr
imhotep
followed the white rabbit


Warum machst du die letzte Schleife nicht so?

C++:
int i;
for (i = 0; Daten1.length() < (_filelength(_fileno(pInfoFile2))); i++) // Den Rest der Datei einlesen
            {
                Sleep(3);
                fread(Daten2,1,1,pInfoFile2); //Jetzt immer nur 1 Byte lesen
                int i = GetLastError();
                if (Daten2[0] != EOF)
                    Daten1[i] = Daten2[0]; // Und Daten in den String
                    Daten1[i+1]
                } else break;
            }
            fclose(pInfoFile2);



willst du unbedingt fread nemmen? mit getc wärs einfacher


C++:
int i;
char c;
for (i = 0; (c = getc(pInfoFile2)) != EOF; i++) // Den Rest der Datei einlesen, EOF == End Of File
            {
                Daten1[i] = c;
                int i = GetLastError();
            }
            Datei1[i++] = '\0'
            fclose(pInfoFile2);



da du weißt, das das File nicht länger als 256 Zeichen ist dürfte es keine Probleme geben.

Dieser Post wurde am 29.08.2005 um 10:27 Uhr von imhotep editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
29.08.2005, 10:55 Uhr
virtual
Sexiest Bit alive
(Operator)


Warum nicht einfach in der C++ Welt bleiben?
Ungetestet:

C++:
#include <fstream>
#include <iterator>
#include <sstream>
#include <algorithm>

std::string readFile(const std::string& fileName) {
   std::ifstream in(fileName.c_str(), std::ios::in|std::ios::binary);
   std::stringstream out;

   in.unsetf(std::ios:skipws);
   std::copy(std::istream_iterator<char>(in),
                 std::istream_iterator<char>,
                 std::ostream_iterator<char>(out));

   return out.str();
}



Wenn es Dir wirklich so um Geschwindigkeit gehen sollte, ist dieser Ansatz übrigens wohl kaum besser als der, 256 Bytes auf einmal zu lesen: Sowohl FILE* alsauch ifstream verwenden intern Buffer; dh das Ständige Umkopieren von den InternenBuffer in einen Bufffer Deines programms und dann nochmal umkopieren in den String ist ja dann der Horror.

Alternative, zum wirklich Schnellen lesen:
1. mittels stat die Größe Der Datei besorgen
2. einen Speicherbereich dieser Größe belegen
3. Datei komplett in diesen Speicher lesen
4. Speichr in String kopieren
5. Speicher freigeben

Solltest Du dennoch mit kleinen Buffern arbeiten, so nimm einen Buffer vonj ca 8 KB Größe und benutze kein FILE* oder stream. Bei heutigen Betriebssystem versprechen 8KB die größte geschwindigkeit, größere Buffer bringen eigentlich nix mehr.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: