下面是一段我自己写的天龙八部明文Txt文件转加密Txt文件的代码.由于我不熟悉Char和16进制文件读写.所以写文件次数很多.希望熟悉16进制文件读写和Char这个数据类型操作的朋友帮忙改改.主要需要优化的是for i := 2 to LoadStringList.Count - 1 do begin[/code]这段.因为按我写的代码如果文件过大的话.写入次数就得几万以上.这样很伤硬盘
procedure TDefaultForm.Menu_Control_SaveClick(Sender: TObject);
var
  DataTypeList, StringData, LineData: TStringList;
  i, j, WriteInt, m_nFileHandle, nStringLine: Integer;
  WriteSin: Single;
begin
  if SaveDialog.Execute then begin
    DataTypeList := TStringList.Create;
    StringData := TStringList.Create;
    StringData.Clear;
    nStringLine := 1;
    LineData := TStringList.Create;
    LineData.Clear;
    SplitStringList(LoadStringList.Strings[0], #9, DataTypeList);
    TrimStringList(DataTypeList);
    MainOutMessage('获取数据类型完成(' + IntToStr(DataTypeList.Count) + ')');
    if FileExists(SaveDialog.FileName) then
      m_nFileHandle := FileOpen(SaveDialog.FileName, fmOpenReadWrite or fmShareDenyNone)
    else
      m_nFileHandle := FileCreate(SaveDialog.FileName);
    FileSeek(m_nFileHandle, 0, 0);
    WriteInt := $DDBBCC00;
    FileWrite(m_nFileHandle, pChar(WriteInt), SizeOf(Integer));
    WriteInt := DataTypeList.Count;
    FileWrite(m_nFileHandle, pChar(WriteInt), SizeOf(Integer));
    WriteInt := LoadStringList.Count - 2;
    FileWrite(m_nFileHandle, pChar(WriteInt), SizeOf(Integer) * 2);
    for i := 0 to DataTypeList.Count - 1 do begin
      If DataTypeList.Strings[i] = 'FLOAT' then
        WriteInt := 1
      else if DataTypeList.Strings[i] = 'STRING' then
        WriteInt := 2
      else
        WriteInt := 0;
      FileWrite(m_nFileHandle, pChar(WriteInt), SizeOf(Integer));
    end;
    MainOutMessage('开始执行数值数据写入(' + IntToStr(LoadStringList.Count) + ')');
    for i := 2 to LoadStringList.Count - 1 do begin
      SplitStringList(LoadStringList.Strings[i], #9, LineData);
      for j := 0 to LineData.Count - 1 do begin
        If DataTypeList.Strings[j] = 'FLOAT' then begin
          WriteSin := Str_ToFloat(LineData.Strings[j], 0.000);
          FileWrite(m_nFileHandle, pChar(WriteSin), SizeOf(Single));
        end else if DataTypeList.Strings[j] = 'STRING' then begin
          FileWrite(m_nFileHandle, pChar(nStringLine), SizeOf(Integer));
          Inc(nStringLine, Length(LineData.Strings[j]) + 1);
          StringData.Add(Trim(LineData.Strings[j]));
        end else begin
          WriteInt := Str_ToInt(LineData.Strings[j], 0);
          FileWrite(m_nFileHandle, pChar(WriteInt), SizeOf(Integer));
        end;
      end;
    end;
    MainOutMessage('开始执行字符数据写入(' + IntToStr(StringData.Count) + ')');
    FileWrite(m_nFileHandle, String(Char(0)), SizeOf(Byte));
    for i := 0 to StringData.Count - 1 do begin
      FileWrite(m_nFileHandle, StringData.Strings[i][1], Length(StringData.Strings[i]));
      FileWrite(m_nFileHandle, String(Char(0)), SizeOf(Byte));
    end;
    FileSeek(m_nFileHandle, 12, 0);
    FileWrite(m_nFileHandle, pChar(nStringLine), SizeOf(Integer));
    FileClose(m_nFileHandle);
    MainOutMessage('数据写入完成');
    DataTypeList.Clear;
    DataTypeList.Destroy;
    StringData.Clear;
    StringData.Destroy;
    LineData.Clear;
    LineData.Destroy;
  end;
end;

解决方案 »

  1.   

    下面是一段我自己写的天龙八部明文Txt文件转加密Txt文件的代码.由于我不熟悉Char和16进制文件读写.所以写文件次数很多.希望熟悉16进制文件读写和Char这个数据类型操作的朋友帮忙改改.主要需要优化的是for i := 2 to LoadStringList.Count - 1 do begin这段.因为按我写的代码如果文件过大的话.写入次数就得几万以上.这样很伤硬盘
      

  2.   

    感觉在循环中FileWrite,有点不合适,你可以吧信息读到自定义结构中,等循环完毕后,一次性将内存中的数据写入文件
      

  3.   

    const max=2047;
    type TwriteBuf=object
            TFH :integer;
            buf:array[0..max] of char;
            dataend:integer;
            procedure write(p:pointer;size:integer);
            procedure init(f:integer);
            procedure writeover;
            end;procedure TwriteBuf.writeover;
    begin
      FileWrite(TFH, @buf[0],dataend);
      dataend:=0;
    end;procedure TwriteBuf.init(f:integer);
    Begin
      TFH:=F;
      dataend:=0;
    End;procedure TwriteBuf.write(p:pointer;size:integer);
    Begin
       if (dataend+size ) > max then writeover ;
       move(p^,buf[dataend],size);
       form1.Caption :=buf;
       inc(dataend,size);
    End;var TWrite:TwriteBuf;
    for i := 2 to LoadStringList.Count - 1 do begin 
    这句之前先 Twrite.init(m_nFileHandle);结束这后,Twrite.writeover;
    把中间的FileWrite(m_nFileHandle, pChar(nStringLine), SizeOf(Integer));
    换成 Twrite.write(pChar(nStringLine), SizeOf(Integer));
      

  4.   

    你的担心是多余的,io访问都有缓冲区的,在缓冲区写满或手动调用FlushFileBuffers之前,根本就不往硬盘上写东西。而且这么做的目的也并不是保护硬盘(硬盘要这么脆弱还谁敢用硬盘了),而是加快速度,因为硬盘的io速度和cpu、内存的速度比起来实在是太慢了
      

  5.   

    不知道你的Txt文件多大,要是10M左右可以一次读入内存,加密后,一次写入.