2012-08-16 8 views
8

En muchos proyectos, vi que el objeto/estructura de datos se escriben en el archivo en modo binario y luego vuelven a recuperarlos del archivo en modo binario.operación de archivo en modo binario vs texto - preocupación por el rendimiento

Me pregunto por qué lo hacen en modo binario? ¿Alguna diferencia de rendimiento entre el texto y el modo binario? Si no, ¿cuándo usar el modo binario o el modo de texto?

+0

Sospecho que es un duplicado de http://stackoverflow.com/questions/229924/difference-between-files-writen-in-binary-and-text-mode, pero no estoy seguro. – jogojapan

+0

@jogojapan, prácticamente. Pero esa publicación no responde completamente mi pregunta. – Alcott

Respuesta

3

Si lee/escribe un archivo en un modo de texto, está operando el texto. Puede ser un tema de errores de codificación y cambios de formato específicos del sistema operativo, aunque a veces puede funcionar bien. En modo binario, sin embargo, no cumplirás con estas restricciones. Además, el modo de texto puede hacer cosas divertidas con los caracteres \n, como reemplazarlos por \n\r.

Fopen referencia, por ejemplo, dice:

En el caso de archivos de texto, dependiendo del entorno en el que los ejecuta la aplicación, algunos de conversión de caracteres especiales pueden ocurrir en operaciones de entrada/salida para adaptarlos a un formato de archivo de texto específico del sistema . En muchos entornos, como la mayoría de los sistemas basados ​​en UNIX, no hace diferencia abrir un archivo como un archivo de texto o un archivo binario; Ambos se tratan exactamente de la misma manera, pero la diferenciación es recomendada para una mejor portabilidad.

+0

este reemplazo quita algo de rendimiento ya que el código tiene que inspeccionar cada carácter. –

+0

@TobiasLangner, por lo que el reemplazo '\ n' /' \ r \ n' ¿será un problema de rendimiento? – Alcott

6

Si su programa es el único que va a usar el archivo, puede guardar las estructuras internas "tal cual" utilizando archivos binarios.

Sin embargo, si desea intercambiar los archivos con otros programas o por Internet, los formatos binarios no son tan buenos. Piensa por ejemplo sobre el problema con las máquinas big-endian vs. little-endian. Además, es probable que el receptor de los archivos o datos no tenga acceso a su código y sus estructuras, por lo que un formato basado en texto podría ser más fácil de analizar e implementar en estructuras propias.

Sobre el rendimiento, es cierto que leer y escribir sus estructuras internas directamente será más rápido, porque no tiene que traducirlas (también conocido como referencias) a otro formato.

+0

+1. Y como señaló, soy el único que usa esos objetos/estructuras de datos, y quiero guardarlos y recuperarlos del archivo. En este caso, no creo que el archivo de texto ayude, con ** archivo de texto **, quiere decir que debería escribir el valor de cada objeto de datos/estructura en el archivo como ** texto sin formato **, y luego leer estos textos de nuevo y usarlos como valor para construir el objeto de datos original? – Alcott

+0

@Alcott Si usted es el único que lee y escribe estos archivos, puede usar el formato binario y simplemente leer/escribir las estructuras directamente.Sin embargo, ¡ten cuidado con los punteros! Al escribir una estructura que contiene un puntero, se escribe el valor real del puntero, no a qué apunta. Cuando lo lea más tarde, ahora apuntará a un área de memoria no asignada. Además, al leer y escribir cadenas, piense en el carácter de terminación '' \ 0''. –

+0

@Alcott Si escribe como texto, puede usar texto simple simple, un valor por línea o varios valores por línea con un separador (por ejemplo, archivos CSV). O use formatos más complicados como XML o JSON. Depende totalmente de ti. :) –

2

Solo unos pocos sistemas operativos se ven afectados por la elección entre el modo binario y el modo de texto. Ninguno de los sistemas Unix o Linux hace nada especial para el modo de texto —, es decir, el texto es el mismo que el binario.

Windows y VMS, en particular, transforman datos en modo texto. Windows transforma \n en \r\n al escribir en un archivo y lo contrario al leer. VMS tiene una estructura de registro de archivo para observar, por lo que en el modo predeterminado, traduce \n en un delimitador de registro.

Donde es diferente, el binario es más rápido. Si no es diferente, no hace ninguna diferencia.

+0

Si es diferente, ¿la diferencia de rendimiento será significativa? – Alcott

+0

@Alcott: en casos normales, no esperaría una diferencia significativa en el rendimiento. Sin embargo, sería fácil construir una prueba donde hay una diferencia significativa simplemente por el uso intensivo de '\ n' y la luz en todo lo demás. En el peor de los casos, Windows duplicaría la cantidad de datos que se escriben y VMS se volvería loco creando muchos registros. – wallyk

15

Binary es más rápido. Considere un entero almacenado en 32 bits (4 bytes), como 123456. Si tuviera que escribir esto como binario (que es como se representa en la computadora) tomaría 4 bytes (ignorando el relleno entre los elementos para la alineación en las estructuras)

Para escribir el número como texto, se debe convertir en una cadena de caracteres (algunos gastos generales para convertir y memoria para almacenar) y luego escribirlos, tomará al menos 6 bytes, ya que hay 6 caracteres para represente el número.Esto no incluye ningún relleno adicional como espacios para alineación o delimitadores para leer/separar los datos.

Ahora, si lo consideramos tiene varios miles de elementos, el tiempo adicional puede sumar y requerir más espacio, lo que llevaría más tiempo para leer y luego está el tiempo adicional para convertir de nuevo a binario para su almacenamiento después de usted he leído el valor en la memoria.

La ventaja del texto es que es mucho más fácil de leer para las personas, en lugar de intentar leer datos binarios o vuelcos hexadecimales de los datos.

+1

Encontré que tu respuesta es más comprensible. :-) – Alcott

2

En el modo binario tiene un tamaño de byte (considere 256) para ser utilizado y en el modo de texto es apenas un poco más de 100 caracteres. Obviamente, ganarás más del doble de tamaño para almacenar datos.
Además, hay casos en los que debe cumplir con las especificaciones de la estructura, como un paquete de red como IPv4.

Tomemos un ejemplo

//No padding 
typedef struct abc 
{ 
int a:4 
char b; 
double c; 
} A[]={{.a=4,.b='a',.c=7.45},{.a=24,.b='z',.c=3.2}} ; 

No es difícil de almacenar los campos de bits en el texto mode.obviously le va suelto para muchas cosas.

Sin embargo, puede guardar el objeto de datos en formato de texto como hecho usando MIME, pero requerirá una rutina adicional para convertirlo en modo binario; Rendimiento martillado.

+0

+1 para el código. En tu código, ¿te refieres a que estoy mejor escribiendo 'A' en el archivo usando el modo de texto? ¿Si es así, cómo? Simplemente escriba el valor de cada miembro de datos en un archivo como texto sin formato y luego vuelva a leer los valores para crear el objeto de datos. – Alcott

+0

:), será muy difícil, puede escribir en modo texto utilizando uno de los métodos llamados XML como ' 4 'pero finalmente tendrá que convertirlo en binario para su funcionamiento normal.En el binario normal solo siga volcando los valores de struct en el archivo.Durante la operación de lectura, si la estructura de destino es de acuerdo con las especificaciones, no tendrá que preocuparse por cómo leer. A medida que el cursor avanza, las matrices seguirán llenándose. – perilbrain

5

Históricamente, el modo binario proporciona un acceso más o menos transparente a la transmisión subyacente; el modo de texto "se normaliza" a una representación de texto estándar , donde las líneas terminan con el carácter '\n' único. Además, el sistema puede imponer restricciones en el tamaño de un archivo binario, por ejemplo, requiriendo que sea un múltiplo de 128 o 512 bytes. (El primero fue el caso de CP/M, el segundo de muchos de los DEC OS). Los archivos de texto no tienen esta restricción, y en los casos en que lo impuso el sistema operativo, la biblioteca típicamente introducirá un extremo adicional del carácter de archivo para archivos de texto. (Incluso hoy, la mayoría de las bibliotecas de Windows reconocen el antiguo archivo CP/M, 0x1A, al leer en el modo de texto ). Debido a estas consideraciones, el modo de texto solo se define sobre un conjunto limitado de valores binarios. (Pero si escribe 200 bytes en un archivo binario , puede recuperar 256 o 512 cuando vuelva a leerlo. Históricamente, el binario solo se debe utilizar para texto que de otra forma esté estructurado, así que para que pueda reconocer la lógica final, e ignore estos bytes adicionales.)

Además, puede buscar casi arbitrariamente en un archivo abierto en el modo binario ; solo puede buscar al principio o en una posición que haya memorizado , en modo texto. (Esto se debe a que la línea que termina asignaciones significan que no hay una relación simple entre la posición en el archivo, y la posición en la secuencia de texto.)

Tenga en cuenta que esto es ortogonal a si la salida se formatea o no : si emite usando << (y la entrada usando >>), el IO se formatea, independientemente del modo en que se abrió el archivo. Y el formato es siempre texto; los iostreams están diseñados para manipular flujos de texto , y solo tienen soporte limitado para entrada y salida sin texto.

Hoy en día, la situación ha cambiado un poco: en muchos casos, esperamos que lo escribimos para ser legible desde otras máquinas, lo que supone un formato definido así , que no puede ser utilizado de forma nativa el formato. (Por lo tanto, para el ejemplo , Internet espera la secuencia de dos bytes 0x0D, 0x0A como una línea final, que es diferente de lo que se usa internamente en Unix y muchos otros sistemas operativos ). Si la portabilidad es una preocupación, generalmente define una , escríbalo explícitamente y use el modo binario para asegurarse de que lo que escriba sea exactamente lo que está escrito; De forma similar en la entrada, utiliza el formato binario y maneja las convenciones de forma manual. Si solo está escribiendo en un disco local, que no se comparte, sin embargo, el modo de texto está bien, y un poco menos trabajo.

Nuevamente, ambos se aplican al texto. Si desea un formato binario, debe usar el modo binario, pero eso está lejos de ser suficiente. Tendrá que implementar todo el IO formateado usted mismo. En tales casos, por lo general no uso o std::istreamstd::ostream (cuyo texto es la abstracción), sino más bien definir mis propios tipos de trenes, que deriva de std::ios_base (para las convenciones de control de errores), y el uso de std::streambuf (por la física IO).

Por último, no olvide que todos IO tiene el formato de alguna manera . Simplemente escribir un bloque de memoria en el archivo significa que el formato es lo que sea que la implementación actual le dé (que generalmente no está documentado, lo que significa que probablemente no podrá leerlo en el futuro). Si todo lo que hace es propagarse al disco, y la única vez que lo leerá es con el mismo programa, compilado con la misma versión del mismo compilador , usando las mismas opciones de compilación, entonces puede simplemente volcar memoria, siempre que la memoria en cuestión sea solo PODs, y no contenga punteros. De lo contrario, debe definir (y documentar) el formato que utiliza e implementarlo. En tales casos, sugeriría usar un formato existente, como XDR, en lugar de inventar el suyo: es mucho más fácil escribir "utiliza el formato XDR" como documentación, en lugar de describiendo el diseño de bit y byte real para todos de los diferentes tipos .

+0

+1 para la respuesta detallada, pero no puedo decir que entiendo completamente, :-). ¿Por qué no puedo buscar arbitrariamente en modo texto? Usando 'seekg (pos)', casi puedo buscar en cada posición del archivo, ¿verdad? – Alcott

+1

@Alcott Porque el estándar dice que es un comportamiento indefinido. Si 'pos' es un valor devuelto por una llamada a' tellg() ', o si' pos' es '0', no hay problema. De lo contrario, es un comportamiento indefinido. (De hecho, funcionará bajo Unix y te colocará un poco más adelante de lo que quieres ir en Windows. ¿Bajo otros sistemas operativos? ¿Quién sabe?) \ –

0

El formato binario es más preciso para almacenar los números ya que están almacenados en la representación interna exacta. No hay conversaciones mientras se guardan los datos y, por lo tanto, el ahorro es mucho más rápido.

Cuestiones relacionadas