[英]TFileStream: Read block of data from file and replace it in Delphi 7
我想從文件中讀取一個字節塊(例如400KB),替換緩沖區中的一些文本,然后將其寫入文件。 最初,我嘗試使用帶有字節緩沖區數組的TFileStream,但是后來我遇到了stringreplace與string一起工作的問題。 源數據是txt UTF-8。 這就是我所擁有的:
var
SS,ST: TFileStream;
Buffer: string;
sf,tf,TempStr: string;
i: Integer;
begin
sf := 'U:\SYSTEM\enwiktionary-latest-stub-articles\stub-articles.xml';
tf := 'A:1.txt';
SS := TFileStream.Create(sf, fmOpenRead);
ST := TFileStream.Create(tf, fmCreate or fmOpenWrite);
try
SS.Read(Buffer, sizeof(Buffer));
Buffer := stringreplace(Buffer, '<page>','<p>', [rfReplaceAll]);
Buffer := stringreplace(Buffer, '</page>','</p>', [rfReplaceAll]);
Buffer := stringreplace(Buffer, '<title>','<t>', [rfReplaceAll]);
Buffer := stringreplace(Buffer, '</title>','</t>', [rfReplaceAll]);
Buffer := stringreplace(Buffer, '<ns>','<n', [rfReplaceAll]);
Buffer := stringreplace(Buffer, '</ns>','>', [rfReplaceAll]);
Buffer := stringreplace(Buffer, '<revision>','<r>', [rfReplaceAll]);
Buffer := stringreplace(Buffer, '</revision>','</r>', [rfReplaceAll]);
Buffer := stringreplace(Buffer, '<id>','<i', [rfReplaceAll]);
Buffer := stringreplace(Buffer, '</id>','>', [rfReplaceAll]);
Buffer := stringreplace(Buffer, '<parentid>','<pi', [rfReplaceAll]);
Buffer := stringreplace(Buffer, '</parentid>','>', [rfReplaceAll]);
Buffer := stringreplace(Buffer, '<contributor>','', [rfReplaceAll]);
Buffer := stringreplace(Buffer, '</contributor>','', [rfReplaceAll]);
Buffer := stringreplace(Buffer, '<username>','<u>', [rfReplaceAll]);
Buffer := stringreplace(Buffer, '</username>','</u>', [rfReplaceAll]);
Buffer := stringreplace(Buffer, '<comment>','<c>', [rfReplaceAll]);
Buffer := stringreplace(Buffer, '</comment>','</c>', [rfReplaceAll]);
Buffer := stringreplace(Buffer, '<text id="','<t =', [rfReplaceAll]);
Buffer := stringreplace(Buffer, '" bytes="',' b=', [rfReplaceAll]);
ST.Write(Buffer, sizeof(Buffer));
finally
SS.Free;
end;
Buffer := stringreplace
使運行時錯誤訪問沖突。
使用UTF8緩沖字符串並為字符串主體分配位置 :
Buffer: AnsiString; //type UTF8String = AnsiString;
...
SetLength(Buffer, BlockSize)
SS.Read(PAnsiChar(Buffer)^, BlockSize);
...
ST.Write(PAnsiChar(Buffer)^, Length(Buffer));
但是,通過這種方法,您可以在塊的邊界松開圖案。 為什么不使用TStringList
,在其中加載所有內容並使用其行?
一個有效的例子。
var
ifname,ofname:string;
sourceStream, targetStream: TFileStream;
filesizevalue, size:integer;
Buffer: AnsiString;
begin
ifname := 'U:\SYSTEM\enwiktionary-latest-stub-articles\stub-articles.xml';
ofname := 'A:1.txt';
filesizevalue:=900000;
size := 1;
SetLength(Buffer, filesizevalue);
sourceStream := TFileStream.Create(ifname, fmOpenRead);
targetStream := TFileStream.Create(ofname, fmCreate or fmOpenWrite);
try
sourceStream.seek(0, soFromBeginning);
sourceStream.ReadBuffer(PAnsiChar(Buffer)^, filesizevalue * size);
buffer := stringreplace(buffer, '<page>','<p>', [rfReplaceAll]);
buffer := stringreplace(buffer, '</page>','</p>', [rfReplaceAll]);
buffer := stringreplace(buffer, '<title>','<t>', [rfReplaceAll]);
buffer := stringreplace(buffer, '</title>','</t>', [rfReplaceAll]);
buffer := stringreplace(buffer, '<ns>','<n', [rfReplaceAll]);
buffer := stringreplace(buffer, '</ns>','>', [rfReplaceAll]);
buffer := stringreplace(buffer, '<revision>','<r>', [rfReplaceAll]);
buffer := stringreplace(buffer, '</revision>','</r>', [rfReplaceAll]);
buffer := stringreplace(buffer, '<id>','<i', [rfReplaceAll]);
buffer := stringreplace(buffer, '</id>','>', [rfReplaceAll]);
buffer := stringreplace(buffer, '<parentid>','<pi', [rfReplaceAll]);
buffer := stringreplace(buffer, '</parentid>','>', [rfReplaceAll]);
buffer := stringreplace(buffer, '<contributor>','', [rfReplaceAll]);
buffer := stringreplace(buffer, '</contributor>','', [rfReplaceAll]);
buffer := stringreplace(buffer, '<username>','<u>', [rfReplaceAll]);
buffer := stringreplace(buffer, '</username>','</u>', [rfReplaceAll]);
buffer := stringreplace(buffer, '<comment>','<c>', [rfReplaceAll]);
buffer := stringreplace(buffer, '</comment>','</c>', [rfReplaceAll]);
buffer := stringreplace(buffer, '<text id="','<t =', [rfReplaceAll]);
buffer := stringreplace(buffer, '" bytes="',' b=', [rfReplaceAll]);
targetStream.Write(PAnsiChar(buffer)^, length(buffer) );
finally
sourceStream.free;
targetStream.free;
end;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.