2009-06-14 11 views
1

Ich habe eine Datei, die ich in einer Binärdatei mit Hilfe von Datensätzen lesen und schreiben möchte. Am Anfang habe ich eine leere Datei und möchte einen neuen Datensatz hinzufügen, aber wenn ich die seekp-Funktion verwende, dann ist die Position bei (-1) ist es ok? Denn wenn ich nachschaue, sehe ich, dass es nichts in die Datei geschrieben hat. Siehe Code:Arbeiten mit fstream-Dateien in Overflow-Verkettung in C++

void Library::addBook(Book newBook) 
{ 
fstream dataFile; 
dataFile.open("BookData.dat", ios::in | ios::out); 
    if (!dataFile) 
    { 
     cerr << "File could not be opened" << endl; 
    } 

int hashResult = newBook.getId() % 4 + 1; // The result of the hash function 

    // Find the right place to place the new book 
    dataFile.seekg((hashResult - 1) * sizeof(Book), ios::beg); 

    Book readBook; 
    dataFile.read(reinterpret_cast<char*>(&readBook), sizeof(Book)); 

    // The record doesnt exist or it has been deleted 
    if (readBook.getId() == -1) 
    { 
     // The record doesnt exist 
     if (readBook.getIdPtr() == -1) 
     { 
      dataFile.seekp((hashResult - 1) * sizeof(Book)); 
      dataFile.write(reinterpret_cast<char*>(&newBook), sizeof(Book)); 

     } 
     // The record has been deleted or there is already such record with such hash function 
     // so we need to follow the pointer to the overflow file 
     else 
     { 
      newBook.setIsBookInData(false); // New book is in overflow file 
      overflowFile.seekg((readBook.getIdPtr() - 1) * sizeof(Book)); 
      overflowFile.read(reinterpret_cast<char*>(&readBook), sizeof(Book)); 
      // Follow the chain 
      while (readBook.getIdPtr() != -1) 
      { 
       overflowFile.seekg((readBook.getIdPtr() - 1) * sizeof(Book)); 
       overflowFile.read(reinterpret_cast<char*>(&readBook), sizeof(Book)); 
      } 
      readBook.setIdPtr(header); // Make the pointer to point to the new book 
      overflowFile.seekp((header - 1) * sizeof(Book)); 
      overflowFile.write(reinterpret_cast<char*>(&newBook), sizeof(Book)); 
      header++; 
     } 
    } 

Wenn mir jemand sagen kann, warum ich nichts in die Datei schreiben kann, werde ich es wirklich schätzen.

Vielen Dank im Voraus,

Greg

+0

:(Niemand weiß, wie es zu lösen ist? –

+0

Wenn es keine Hausaufgaben ist, dann verwenden Sie keine vorhandenen Lösungen, z. B. Boost.Serialization, wenn Sie Serialisierung benötigen, 'Google Protocol Buffers' zum Austauschen binärer Daten zwischen Programmen (oder irgendeine Bibliothek für XML, JSON, wenn Textformate akzeptabel sind), 'sqlite' für eine leichte Datenbanklösung? – jfs

Antwort

2

Nun, hier sind ein paar Vorschläge, die helfen können:

  • wenn Sie die Datei öffnen, verwenden ios_base :: Binärmerker
  • stellen Sie sicher, dass Buch ist ein POD (dh ein C kompatibel Typ)
  • stellen Sie sicher, dass, wenn Sie lesen oder schreiben, dass der Strom vor in einem gültigen Zustand ist und nach
  • nicht verwenden readBook.getId() == -1, wenn die Lese sicher
  • machen konnte zu prüfen, ob bei du suchst in den Strom du bist nicht g oing über das Ende der Datei
  • die Puffer verwenden, um die Gesamtzahl des Bytes in der Datei zu erhalten und dann sicherzustellen, dass Sie es nicht überschreiten, bevor
  • suchen, wann immer Sie suchen, macht einen relativ suchen (Verwendung ios_base :: betteln um zB)
  • Verwendung static_cast<char*>(static_cast<void*>(&book)) vs reinterpret cast<char*>

Wenn Sie spezielle Fragen zu einem dieser Vorschläge haben, lassen Sie uns wissen, und vielleicht können wir Sie besser führen.

1

Du liest gerade scheinbar über das Ende der Datei. Ihr seekg Aufruf wahrscheinlich bewegt den Lesezeiger über das Ende, dann rufen Sie lesen. Dadurch wird der Stream in einen Fehlerzustand versetzt. Prüfen Sie dies, indem Sie:

std::cout << dataFile.fail() << std::endl; 

nach dem Aufruf gelesen.

Die Art der Datensatzverwaltung, die Sie versuchen, ist keine triviale Aufgabe. Vielleicht sollten Sie eine serverlose DBE wie SQLite oder andere Serialisierungsbibliotheken wie versuchen.

Auch sollten Sie Ihre Datei mit dem ios :: binary Flag auch öffnen.