[C++] std::ofstream.seekp() veroorzaakt corrupt bestand

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • cyberstalker
  • Registratie: September 2005
  • Niet online

cyberstalker

Eersteklas beunhaas

Topicstarter
Ik krijg het niet voor elkaar om met std::ofstream.seekp() te werken. Ik krijg altijd een corrupt bestand. Het gaat mis bij de volgende code

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
inline void file::write_part(segment *the_segment, ::nntp::decoded_article_ptr decoded)
{
    boost::mutex::scoped_lock   lock(write_mutex);  // make sure we are the only ones messing with segments
    std::string                 filename;           // cache file name
    std::string                 data;               // cache decoded data

    // get the filename and data from the decoded article
    decoded->filename(filename, false);
    decoded->data(data);

    // open file
    out_file.open(filename.c_str(), std::ios_base::binary | std::ios_base::out);

    // if it is a multipart binary, seek to the right position
    if (decoded->multipart())
        out_file.seekp(decoded->begin() - 1);

    // did we arrive at the right position?
    if (decoded->multipart() && out_file.tellp() != decoded->begin() - 1)
        std::cout << "File '" << filename << "', segment " << the_segment->segment_number() <<  " at position " << out_file.tellp() << ", expected to be at " << decoded->begin() - 1 << std::endl;

    // write the data
    out_file.write(data.c_str(), data.length());

    // close the file
    out_file.close();
}


Hou ik daarentegen het bestand open, en zoek ik niet in het bestand, dan gaat het wel goed. Ik moet dan alleen wel de netjes alles in de goede volgorde aan de functie aangeven. De volgende code werkt in dit geval dus wel:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
inline void file::write_part(segment *the_segment, ::nntp::decoded_article_ptr decoded)
{
    boost::mutex::scoped_lock   lock(write_mutex);  // make sure we are the only ones messing with segments
    std::string                 filename;           // cache file name
    std::string                 data;               // cache decoded data

    // get the filename and data from the decoded article
    decoded->filename(filename, false);
    decoded->data(data);

    // open file if necessary
    if (!out_file.is_open())
        out_file.open(filename.c_str(), std::ios_base::binary | std::ios_base::out);

    // are we at the right spot?
    if (decoded->multipart() && out_file.tellp() != decoded->begin() - 1)
        std::cout << "File '" << filename << "', segment " << the_segment->segment_number() <<  " at position " << out_file.tellp() << ", expected to be at " << decoded->begin() - 1 << std::endl;

    // write the data
    out_file.write(data.c_str(), data.length());

    // close the file
    if (the_segment->segment_number() == segment_list.size())
        out_file.close();
}


Ik controleer hier dus of de write position correct is, door de uitkomst van tellp() te vergelijken met wat ik verwacht. Dit doe ik in het eerste geval ook, en na de seekp() werkt dit ook. Alleen, het eerste geval creëert een corrupt bestand en ik heb geen idee waar dat door kan komen. De reden dat ik dit werkend wil krijgen is dat dan de gegevens in willekeurige volgorde kunnen worden geschreven.

out_file is een member variabele van de class file, article is een smart pointer naar een gedecodeerd usenet artikel. Hoe krijg ik seekp() werkend?

Ik ontken het bestaan van IE.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Heb je het nog opgelost?

Ik zie niet zo snel iets. Wat gaat er precies fout; hoe is het corrupted? Zet eens je exceptions aan (out_file.exceptions(std::ios::failbit | std::ios::badbit | std::ios::eofbit);) Of je open mode als std::ios::trunc ofzo? (sowieso moet je meer error checking doen op I/O; er kan zo veel fout gaan, en dan wil je niet je data kwijt zijn)

[ Voor 27% gewijzigd door Zoijar op 25-01-2011 12:44 ]


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 15:26
C++:
1
2
3
4
5
6
7
 ....
   // open file
    out_file.open(filename.c_str(), std::ios_base::binary | std::ios_base::out);

    // if it is a multipart binary, seek to the right position
    if (decoded->multipart())
        out_file.seekp(decoded->begin() - 1);


Volgens mij gaat dit alleen goed als decoded->begin() - 1 nul is aangezien ofstream.open je bestand truncate tot 0.

[edit]
Hmm nu weet ik het niet meer zeker, de docs suggereren dat je daaarvoor expliciet std::ios_base::trunc zou moeten meegeven.

[ Voor 14% gewijzigd door farlane op 25-01-2011 16:39 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • cyberstalker
  • Registratie: September 2005
  • Niet online

cyberstalker

Eersteklas beunhaas

Topicstarter
Ik heb de bron van het probleem gevonden. Zoeken in een bestand maakt het bestand leeg, tenzij je std::ios_base::in ook bij de open meegeeft.

Dus, farlane, je had toch gelijk, het bestand werd leeggemaakt, dus alles vóór het blok wat ik schreef verdween.

Ik ontken het bestaan van IE.