Delphi-如何在保存前删除非ANSI(不可打印)字符?
有没有人能指导我扩展这个过程,让它在将流保存到文件之前删除所有不可打印的字符或用空格替换?字符串是从二进制文件读取的,最大大小可能为1 MB。 我的程序:Delphi-如何在保存前删除非ANSI(不可打印)字符?,delphi,stream,save,Delphi,Stream,Save,有没有人能指导我扩展这个过程,让它在将流保存到文件之前删除所有不可打印的字符或用空格替换?字符串是从二进制文件读取的,最大大小可能为1 MB。 我的程序: var i : Word; FileName : TFileName; SizeofFiles,posi : Integer; fs, sStream: TFileStream; SplitFileName: String; begin ProgressBar1.Position := 0; FileName:=
var
i : Word;
FileName : TFileName;
SizeofFiles,posi : Integer;
fs, sStream: TFileStream;
SplitFileName: String;
begin
ProgressBar1.Position := 0;
FileName:= lblFilePath.Caption;
SizeofFiles := StrToInt(edt2.Text) ;
posi := StrToInt(edt1.text) ;
fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
fs.Position := Posi ;
begin
SplitFileName := ChangeFileExt(FileName, '.'+ FormatFloat('000', i));
sStream := TFileStream.Create(SplitFileName, fmCreate or fmShareExclusive);
try
if fs.Size - fs.Position < SizeofFiles then
SizeofFiles := fs.Size - fs.Position;
sStream.CopyFrom(fs, SizeofFiles);
ProgressBar1.Position := Round((fs.Position / fs.Size) * 100);
finally
sStream.Free;
end;
end;
finally
fs.Free;
end;
end;
var
一:字;
文件名:TFileName;
SizeofFiles,posi:Integer;
fs,sStream:TFileStream;
SplitFileName:String;
开始
ProgressBar1.位置:=0;
文件名:=lblFilePath.Caption;
SizeofFiles:=stroint(edt2.Text);
posi:=stroint(edt1.text);
fs:=TFileStream.Create(文件名、fmOpenRead或fmShareDenyWrite);
尝试
fs.位置:=Posi;
开始
SplitFileName:=ChangeFileExt(文件名“.”+FormatFloat('000',i));
sStream:=TFileStream.Create(SplitFileName、fmCreate或fmShareExclusive);
尝试
如果fs.Size-fs.Position
您将无法再使用TStream.CopyFrom()
。您必须从源TStream
中读取(缓冲区)(
到本地字节数组中,从该数组中去除您不需要的任何内容,然后写入(缓冲区)(
剩余字节到目标TStream
以下是一个简单的演示,它可以满足您的需要:
const
SrcFileName : String = 'Test.txt';
DstFileName : String = 'TestResult.txt';
StartPosition : Int64 = 50;
procedure TForm1.Button1Click(Sender: TObject);
var
FS : TFileStream;
Buf : TBytes;
I : Integer;
begin
// Read the source file from starting position
FS := TFileStream.Create(SrcFileName, fmOpenRead or fmShareDenyWrite);
try
FS.Position := StartPosition;
SetLength(Buf, FS.Size - FS.Position);
FS.Read(Buf[0], Length(Buf));
finally
FreeAndNil(FS);
end;
// Replace all non printable character by a space
// Assume file content is ASCII characters
for I := 0 to Length(Buf) - 1 do begin
// You may want to make a more complex test for printable of not
if (Ord(Buf[I]) < Ord(' ')) or (Ord(Buf[I]) > 126) then
Buf[I] := Ord(' ');
end;
// Write destination file
FS := TFileStream.Create(DstFileName, fmCreate);
try
FS.Write(Buf[0], Length(Buf));
finally
FreeAndNil(FS);
end;
end;
const
SrcFileName:String='Test.txt';
DstFileName:String='TestResult.txt';
起始位置:Int64=50;
程序TForm1.按钮1单击(发送方:TObject);
变量
FS:TFileStream;
Buf:TBytes;
I:整数;
开始
//从起始位置读取源文件
FS:=TFileStream.Create(SrcFileName、fmOpenRead或fmShareDenyWrite);
尝试
FS.位置:=起始位置;
设置长度(Buf,FS.Size-FS.Position);
FS.Read(Buf[0],长度(Buf));
最后
FreeAndNil(FS);
结束;
//用空格替换所有不可打印字符
//假设文件内容是ASCII字符
对于I:=0到长度(Buf)-1,开始
//您可能需要对not的可打印性进行更复杂的测试
如果(Ord(Buf[I])126),则
Buf[I]:=Ord(“”);
结束;
//写入目标文件
FS:=TFileStream.Create(DstFileName,fmCreate);
尝试
FS.Write(Buf[0],长度(Buf));
最后
FreeAndNil(FS);
结束;
结束;
此代码假定文件是纯ASCII文本,并且ASCII代码低于32(空格)或高于126的每个字符都不可打印。欧洲语言可能并非如此。您可以轻松调整测试以满足您的需要
源文件也可以是Unicode(16位字符)。您应该使用由Unicode字符或16位整数(Word)组成的缓冲区。并将测试调整为可打印
也可以是UTF8…谢谢你们的帮助。祝你玩得愉快:-)