2011-01-23 9 views
14

Zrobiłem narzędzie w Delphi, aby stworzyć tęczowy stół. To było w porządku, dopóki plik nie zwiększył rozmiaru do 3,1 GB. Zamknąłem swój program. Potem otworzył je ponownie i to wywala podczas wykonywania tego kodu:Delphi Pascal - jak zapisać dane do pliku większego niż 2 GB?

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

Delphi pokazuje błąd „podniesione klasy expection EInOutError z komunikatem«I/O error 131» Moje pytanie. Jak dodać dane do istniejącego pliku większego niż 2 GB // Przestarzałe Następne pytanie:. mam obecnie kod:..

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

Jak pozbyć zmiennej Content_to_file chcę umieścić go bezpośrednio do WriteBuffer jeśli `s możliwe

EDYTOWANIE:

TFileStream działa z plikami o wielkości powyżej 2 GB. Przetestowałem to teraz. Jednak możliwe jest napisać tak:

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

Znaczy przekazać żadnej zmiennej argumentu. Czy mam zdecydowanie przekazać pierwszy znak zmiennej?

EDIT 2:

Mam aktualnie wykonane to w ten sposób:

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

to możliwe, aby to zrobić bez tej zmiennej?

+2

Czy twój system plików obsługuje pliki> 2 GB? – Satya

+0

Tak, robi. Mam 32-bitowy system Windows XP. Obecnie plik ma 3,1 GB na mojej partycji NTFS. Problem dotyczy mojego kodu paskowego. – fastman92

Odpowiedz

8

Zwykły proces I/O nie nadaje się do nowoczesnych operacji. Po prostu użyj klasy TFileStream lub, jeśli potrzebujesz dokładnej kontroli, skorzystaj bezpośrednio z interfejsu API Windows (przeczytaj o funkcjach CreateFile i WriteFile).

+2

"Zwykły proces I/O nie nadaje się do nowoczesnych operacji." Czym są te tak zwane "nowoczesne operacje", o których mówisz? – dummzeuch

+3

@dummzeuch pisząc poza 2 Gb jest doskonale poprawną * nowoczesną * operacją i tak też jest czytanie. –

+0

Tłumaczenie: to błąd, a Embarcadero nie wydaje się tym przejmować. –

24

Powinieneś przełączyć na strumienie. A TFileStream poradzi sobie z tym bez problemów. Pamiętaj, że jeśli korzystasz z dostępu losowego, musisz upewnić się, że używasz 64-bitowych wersji Seek i Position.

Po otwarciu pliku strumienia można szukać do końca:

Stream.Seek(0, soEnd); 

Następnie można pisać wiersze, jak tak:

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

Mam nadzieję, że powinno dać wystarczająco dużo wskazówek, aby wypełnić w pozostałych szczegółach.

+0

Kolejnym oczywistym pytaniem jest, jak pisać wiele argumentów() do strumienia. Jednym z powodów, dla których potrzebuję tylko strumieni. –

+0

@Marco Nie byłoby problemu z wymyśleniem takiej procedury i zawinięcie jej do istniejącej klasy strumienia. Osobiście raczej nie używam bezpośrednio klas strumieni dostarczanych z Delphi, ale zamiast tego wolę moje własne podklasowane wersje, które dodają dodatkowe funkcje, aby zaspokoić moje potrzeby. W szczególności mam strumień plików, który buforuje I/O ze względu na wydajność i strumień pamięci, który blokuje alokację zamiast wymagającej ciągłej pamięci. –

+0

Wtedy naprawdę chciałbym to zobaczyć. Write (lN) używa magii kompilatora. Może być kilka sposobów, by zadziwić się z systemem textrec, ale jeśli to zrobisz, równie dobrze możesz rozwiązać problemy 64-bitowe bezpośrednio. Strumienie są IMHO po prostu nie bardzo wygodne dla plików tekstowych. –