2011-11-25 34 views
5

que estoy tratando de lograr algo como esto:lectura trozos de un archivo en modo binario a un búfer y escrito que buffer en otro archivo

while (ifstream has not been entirely read) 
{ 
    read a chunk of data into a buffer that has size BUFLEN 
    write this buffer to ostream 
} 

Al principio trataron de lograr esto mediante el uso de ifstream.eof() como mi mientras condición, pero he oído que este no es el camino a seguir. He estado buscando otras funciones de std :: ios :: ifstream, pero no puedo imaginar qué más usar.

PD: Estoy usando un búfer porque el archivo que se está transfiriendo puede ser muy grande.

Respuesta

7

Las clases iostream se encargan de todo el almacenamiento en memoria intermedia necesario, por lo que no debe hacer . La expresión habitual para copiar un archivo completo es simplemente:

fout << fin.rdbuf(); 

iostream se encarga de todo el almacenamiento en memoria intermedia necesario. (Este es un uso un tanto inusual de <<, ya que no da formato. históricos razones, sin duda.)

Si necesita el bucle, tal vez debido a que desea hacer algunas transformaciones en los datos antes de volver a escribir es, entonces, es un pequeño tricker, ya que istream::read “ falla ” a menos que lea el número solicitado de caracteres. Debido a esto, hay que comprobar también cómo se leyeron muchos personajes, y procesarlos, incluso si la lectura ha fallado:

int readCount; 
while (fin.read(&buf[0], buf.size()) 
     || (readCount = fin.gcount()) != 0) { 
    // ... 
    fout.write(&buf[0], readCount); 
} 

Esto es bastante fea; una solución mejor podría ser envolver el búfer en una clase y definir un operator<< para esta clase.

+0

Entonces, si tengo que leer un archivo muy grande y escribirlo en otro archivo, no debo preocuparme por usar un buffer, ¿ya lo hace iostream? Sin embargo, lo estoy haciendo porque estoy enviando los datos a través de TCP en una etapa posterior. Gracias por el código, lo intentaré ahora. – codd

+0

¡Sin embargo, el código funciona! ¡Gracias! – codd

+0

En otra nota: ¿esto también debería funcionar cuando trabajo con archivos que no son de texto? Porque necesito poder hacer esto con cualquier tipo de archivo (pdf, mp3, ...). Y no parece funcionar en un pdf con el que lo probé. – codd

0

Su lógica es simplemente incorrecta.

Es necesario ir sobre él de la misma familia:

while (a chunk larger than zero could be read) 
{ 
    write chunk to output 
} 

Vea cómo esto es aún más simple? No es necesario verificar explícitamente el "final del archivo", solo lea los datos hasta que falle. Entonces has terminado.

+0

Veo lo que quiere decir. Intenté lograr eso usando read() como condición, pero read() me dio un archivo vacío y! Read() siguió reescribiendo mi archivo con basura entre las copias. ¿Te importaría elaborar y darme funciones específicas para usar? – codd

6

La función istream::read devuelve la corriente, que puede ser utilizado como una expresión booleana, por lo que se puede hacer algo como:

while (is.read(buffer, BUFLEN)) 
{ 
    outputfile.write(buffer, is.gcount()); 
} 

if (is.eof()) 
{ 
    if (is.gcount() > 0) 
    { 
     // Still a few bytes left to write 
     outputfile.write(buffer, is.gcount()); 
    } 
} 
else if (is.bad()) 
{ 
    // Error reading 
} 

Es posible que desee comprobar que la escritura dentro del bucle no deja demasiado .

+0

El siguiente código me dio un nuevo archivo vacío, ¿quizás sabes cuál es el problema? 'while (is.read (buffer, BUFLEN)) {outfile.write (buffer, BUFLEN); } ' – codd

+0

@codd Extendí mi código de ejemplo. Lo intenté yo mismo. –

+0

Gracias por el código de ejemplo Joachim. ¡Esto también parece funcionar con otros archivos como el pdf, etc.! – codd

Cuestiones relacionadas