2011-01-23 12 views
14

Ho creato uno strumento in Delphi per creare un tavolo arcobaleno. Andava bene fino a quando il file è cresciuto fino a 3.1 GB. Ho chiuso il mio programma. Poi ho aperto di nuovo e si blocca durante l'esecuzione di questo codice:Delphi Pascal: come scrivere i dati su file più grandi di 2 GB?

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

Delphi mostra errore "sollevato EInOutError classe expection con il messaggio 'I/O error 131' La mia domanda:. Come aggiungere dati al file esistente più grande di 2 GB // obsoleto Prossima domanda:. ho attualmente il codice:..

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

Come sbarazzarsi di variabile Content_to_file voglio metterlo direttamente al WriteBuffer se esso `s possibile

012.

MODIFICA:

TFileStream funziona con file di dimensioni superiori a 2 GB. L'ho provato ora. è tuttavia possibile scrivere così:

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

intendo passare alcun argomento variabile. O devo assolutamente passare il primo carattere di variabile?

EDIT 2:

ho attualmente composto in questo modo:

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

E 'possibile farlo senza questa variabile?

+2

Il file system supporta file> 2 GB? – Satya

+0

Sì, lo fa. Ho Windows XP a 32 bit. Attualmente il file è di 3.1 GB sulla mia partizione NTFS. Il problema è con il mio codice pascal. – fastman92

risposta

8

I/O procedura semplice non è adatto per operazioni moderne. Basta usare la classe TFileStream o, se hai bisogno di un controllo preciso, utilizzare direttamente l'API di Windows (leggi le funzioni CreateFile e WriteFile).

+2

"I/O procedura semplice non è adatto per operazioni moderne." Quali sono queste cosiddette "operazioni moderne" di cui stai parlando? – dummzeuch

+3

@dummzeuch scrivere oltre 2Gb è un'operazione * moderna * perfettamente valida, così come la lettura. –

+0

Traduzione: è un bug, e all'Embarcadero non sembra importare. –

24

È necessario passare agli stream. A TFileStream gestirà questo senza problemi. Si noti che se si utilizza l'accesso casuale, è necessario assicurarsi di utilizzare le versioni a 64 bit di Seek e Position.

Dopo aver aperto il flusso di file si può cercare fino alla fine:

Stream.Seek(0, soEnd); 

Poi si può scrivere come linee così:

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

Si spera, che dovrebbe darvi abbastanza indizi per riempire nel resto dei dettagli.

+0

La prossima domanda ovvia è come scrivere in un multi-argomento write() in un flusso. Uno dei motivi per cui ho bisogno di flussi solo quando ne ho bisogno. –

+0

@Marco Non sarebbe molto difficile elaborare una tale routine e avvolgerla attorno a una classe di stream esistente. Personalmente tendo a non utilizzare direttamente le lezioni di streaming fornite con Delphi, preferendo invece le mie versioni sottoclasse che aggiungono funzionalità extra per soddisfare le mie esigenze. In particolare, ho un flusso di file che bufferizza l'I/O per motivi di prestazioni e un flusso di memoria che blocca allocati piuttosto che esigente memoria contigua. –

+0

Allora mi piacerebbe davvero vederlo. Write (lN) usa la magia del compilatore. Ci sono alcuni modi magari facendo scherzi con il sistema textrec, ma se lo fai potresti anche risolvere direttamente i problemi a 64 bit. Gli stream IMHO semplicemente non sono molto comodi per i file di testo. –

Problemi correlati