2010-04-01 11 views
11

Potrzebuję otworzyć plik z wyprzedzeniem i napisać na początku pliku, zachowując pozostałą zawartość pliku, który zostanie "przeniesiony". Podobne do "z góry" plik.C++ napisz na początku pliku

Czy jest to możliwe przy użyciu STL lub boost?

Odpowiedz

5

Nie, nie jest. To pytanie było już wielokrotnie zadawane. Jeśli chcesz to zrobić, musisz utworzyć nowy plik, zapisać do niego dane "z góry", a następnie otworzyć istniejący plik i skopiować jego zawartość do nowego pliku.

16

Nie - język (lub biblioteka) nie ma tu większego znaczenia. Większość systemów plików po prostu na to nie pozwala, kropka.

Najczęstszym sposobem uzyskania tego samego efektu jest zapisanie nowych danych do nowego pliku, a następnie skopiowanie danych ze starego pliku do nowego pliku po zapisaniu danych.

+0

Jak możesz powiedzieć, że to niemożliwe, a następnie opisać, jak to zrobić? Boost zapewnia przenośną bibliotekę systemu plików http://www.boost.org/doc/libs/1_42_0/libs/filesystem/doc/index.htm z 'boost :: remove', która w rzeczywistości robi różnicę, jeśli chcesz rozłączyć stary plik i utworzyć nowy plik - nie jest to konieczne, ani nawet dobry sposób na jego wdrożenie. OP nie poprosił o jedno-liniowy, poprosił o pomoc. – Potatoswatter

+6

Nie opisuje, jak to zrobić; opisuje standardowe obejście tego problemu. – Nate

+0

Uh, jako obejście oznaczałoby wykonanie tego zadania. Co więcej, używamy C++, ponieważ jest przenośny, a język i biblioteka * robią * różnicę, ponieważ do rozwiązania problemu wykorzystywane są bardzo specyficzne funkcje. Zobacz moją odpowiedź. – Potatoswatter

1

Nowa klasa iostream może owijać tę funkcjonalność. Zakłada to, że twoje dane z wyprzedzeniem nie są zbyt duże, by wygodnie zmieścić się w pamięci. Użyj go jak zwykłego ofstream.

#include <fstream> 
#include <sstream> 
#include <vector> 

class prepend_ofstream 
    : public std::ostringstream { 
    std::filebuf file; 
public: 
    prepend_ofstream() {} 
    prepend_ofstream(char const *name, openmode mode = out) { 
     open(name, mode); 
    } 
    ~prepend_ofstream() { 
     if (is_open()) close(); 
    } 
    void open(char const *name, openmode mode) { 
     if (! file.open(name, mode & binary | in | out)) { 
      setstate(failbit); 
     } 
    } 
    bool is_open() { return file.is_open(); } 
    void close() { 
     if (! is_open()) { 
      setstate(failbit); 
      return; 
     } 
     char *strbuf = &str()[0]; 
     std::vector<char> buf(str().size()); 
     int rdsz; 
     do { 
      rdsz = file.sgetn(&buf[0], buf.size()); 
      file.pubseekoff(-rdsz, cur); 
      file.sputn(strbuf, buf.size()); 
      file.pubseekoff(0, cur); // "update the output sequence" 
      std::copy(&buf[0], &buf[0]+rdsz, strbuf); 
     } while (rdsz == buf.size()); 
     file.sputn(&buf[0], rdsz); 
     if (! file.close()) { 
      setstate(failbit); 
     } 
    } 
}; 

Typowo są dodawane przez cechy nowego strumienia bufor klas, a nie rzeczywiste strumieni, ale w tym przypadku nowych funkcji w close, który nie jest jeszcze wirtualny.