2011-01-23 14 views
14

Hice una herramienta en Delphi para crear una tabla de arcoíris. Estuvo bien hasta que el archivo creció hasta 3.1 GB. Cerré mi programa. Entonces me abrió de nuevo y se bloquea durante la ejecución de este código:Delphi Pascal: cómo escribir datos en un archivo de más de 2 GB?

Assign(RainbowFile,'Rainbow_table.txt'); {assign a text file} 
Append(RainbowFile); 

Delphi muestra el error "levantado EInOutError clase expection con el mensaje 'I O error 131 /' Mi pregunta:. Cómo añadir datos al archivo existente grande de 2 GB // obsoleto siguiente pregunta:. tengo Actualmente código:..

Content_to_file := (#13+#10+Start_string+':'+hexstr(GTA_San_Andreas_CRC32(Start_string), 8)); 
    RainbowFile_handle.WriteBuffer(Content_to_file[1], Length(Content_to_file)*SizeOf(Char)); 

¿Cómo deshacerse de la variable Content_to_file quiero ponerlo directamente a la WriteBuffer si `s posible

EDITAR:

TFileStream funciona con archivos de más de 2 GB. Lo probé ahora. Sin embargo es posible escribir así:

RainbowFile_handle.WriteBuffer(Start_string[1]+':', 

me refiero a pasar ningún argumento variable. ¿O definitivamente he pasado el primer carácter de la variable?

EDIT 2:

que actualmente he hecho de esta manera:

Content_to_file := (#13+#10+Start_string+':'+hexstr(GTA_San_Andreas_CRC32(Start_string), 8)); 
    RainbowFile_handle.WriteBuffer(Content_to_file[1], Length(Content_to_file)*SizeOf(Char)); 

¿Es posible hacerlo sin esta variable?

+2

¿Su sistema de archivos admite archivos> 2 GB? – Satya

+0

Sí, lo hace. Tengo Windows XP de 32 bits. Actualmente el archivo es de 3.1 GB en mi partición NTFS. El problema es con mi código pascal. – fastman92

Respuesta

8

La E/S de procedimiento simple no es adecuada para operaciones modernas. Solo use la clase TFileStream o, si necesita un control preciso, use la API de Windows directamente (lea sobre las funciones CreateFile y WriteFile).

+2

"La E/S de procedimiento simple no es adecuada para operaciones modernas". ¿De qué se trata estas llamadas "operaciones modernas" de las que está hablando? – dummzeuch

+3

@dummzeuch escribiendo más allá de 2Gb es una operación * moderna * perfectamente válida, y lo mismo ocurre con la lectura. –

+0

Traducción: es un error, y Embarcadero no parece importarle. –

24

Debe cambiar a las transmisiones. Un TFileStream se encargará de esto sin problemas. Tenga en cuenta que si usa acceso aleatorio, debe asegurarse de utilizar las versiones de 64 bits de Seek y Position.

Después de haber abierto la secuencia de archivo se puede buscar hasta el final:

Stream.Seek(0, soEnd); 

A continuación, puede escribir líneas como tan:

procedure StreamWriteLine(Stream: TFileStream; Text: string); 
begin 
    Text := Text + sLineBreak; 
    Stream.WriteBuffer(Text[1], Length(Text)*SizeOf(Char)); 
end; 

Con suerte, que debe darle pistas suficientes para llenar en el resto de los detalles.

+0

La siguiente pregunta obvia es cómo escribir un argumento múltiple() en una secuencia. Una de las razones por las que solo necesito transmisiones cuando lo necesito. –

+0

@Marco No sería muy difícil crear una rutina así y envolverla en una clase de transmisión existente. Personalmente, no suelo utilizar directamente las clases de flujo suministradas con Delphi, sino que prefiero mis propias versiones subclasificadas que agregan funcionalidad adicional para satisfacer mis necesidades. En particular, tengo una secuencia de archivos que almacena temporalmente las E/S por motivos de rendimiento y una secuencia de memoria que bloquea asigna en lugar de exigir memoria contigua. –

+0

Entonces realmente me gustaría ver eso. Write (lN) usa la magia del compilador. Hay algunas maneras, tal vez jugando con el sistema textrec, pero si lo hace, también puede corregir los problemas de 64 bits directamente. Los flujos son en mi humilde opinión simplemente no es muy cómodo para los archivos de texto. –

Cuestiones relacionadas