lavorare con fstream file in overflow il concatenamento in c++
Domanda
Ho un file che voglio leggere e scrivere un file binario che utilizza i record.All'inizio ho un file vuoto e voglio aggiungere un nuovo record, ma quando uso il seekp funzione, quindi la posizione è a (-1) è ok?Perché quando posso controllare, vedo che non è scritto nulla al file.Vedere il codice:
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++;
}
}
Se qualcuno mi può dire perché non posso scrivere il file che ho davvero considerare esso.
Grazie in anticipo,
Greg
Soluzione
Bene, qui sono alcuni suggerimenti che possono aiutare:
- quando si apre il file, utilizzare ios_base::flag binario
- assicurarsi che il Libro è un CONTENITORE (es.a C tipo compatibile)
- assicurarsi che durante la lettura o la scrittura che il flusso è in uno stato valido prima e dopo
- non utilizzare readBook.getId() == -1 per verificare se la lettura è riuscito
- assicurarsi che quando si cercano nel flusso non si sta andando oltre la fine del file
- usare il buffer per ottenere il numero totale di byte del file e quindi garantire che non superino prima di chiedere
- ogni volta che si cercano, non un parente seek (uso ios_base::beg e.g)
- utilizzare
static_cast<char*>(static_cast<void*>(&book))
vsreinterpret cast<char*>
Se avete domande specifiche su qualsiasi di questi suggerimenti, facci sapere e magari ti possiamo aiutare meglio.
Altri suggerimenti
Stai leggendo apparentemente oltre la fine del file. Il tuo seekg chiamata è probabilmente spostando il puntatore leggere oltre la fine, quindi si chiama leggere . Questo imposterà il vostro flusso in uno stato non riuscire. Controllare questo facendo:
std::cout << dataFile.fail() << std::endl;
dopo il lettura di chiamata.
Il tipo di gestione dei record che si sta tentando di fare non è un compito banale. Forse si dovrebbe cercare un DBE serverless come SQLite o altro serializzazione librerie come Boost.Serialization .
Inoltre, si dovrebbe aprire il file con ios :: binary segnala come pure.