2010-04-01 15 views
11

Necesito abrir un archivo como fuente y escribir en la parte delantera del archivo, preservando el contenido restante del archivo, que se "moverá". Similar a "anteponer" un archivo.C++ escribir al frente del archivo

¿Es esto posible utilizar STL o boost?

Respuesta

5

No, no lo es. Y esto se ha preguntado aquí muchas veces antes. Si desea hacer esto, debe crear un nuevo archivo, escribir los datos de "anteponer" a él, luego abrir el archivo existente y copiar su contenido al nuevo archivo.

16

No, el idioma (o biblioteca) realmente no hace mucha diferencia aquí. La mayoría de los sistemas de archivos simplemente no lo permiten, punto.

La forma habitual de obtener el mismo efecto es escribir sus datos nuevos en un archivo nuevo, y luego copiar los datos en el archivo anterior en el nuevo archivo siguiendo los datos que escribió.

+0

¿Cómo puede decir que es imposible y luego describir cómo hacerlo? Boost proporciona una biblioteca de sistema de archivos portátil http://www.boost.org/doc/libs/1_42_0/libs/filesystem/doc/index.htm con 'boost :: remove', que de hecho hace una diferencia si desea desvincularse el archivo anterior y crea un archivo nuevo; no es que sea esencial, ni siquiera una buena forma de implementarlo. OP no pidió un trazador de líneas, pidió ayuda. – Potatoswatter

+6

Él no describe cómo hacerlo; él describe la solución estándar para este problema. – Nate

+0

Uh, ser una solución implicaría realizar la tarea. Más al punto, usamos C++ porque es portátil, y el lenguaje y la biblioteca * hacen * la diferencia porque se usan características muy específicas para resolver el problema. Ver mi respuesta – Potatoswatter

1

Una nueva clase iostream puede ajustar esa funcionalidad. Esto supone que sus datos de preposición no son demasiado grandes para que quepan cómodamente en la memoria. Úselo como un ofstream normal.

#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); 
     } 
    } 
}; 

Típicamente características se añaden a través de nueva corriente clases tampón, no corrientes reales, pero en este caso la nueva funcionalidad es en close, que desgraciadamente no es virtual.

Cuestiones relacionadas