ファイルは一度に読もう(TFileStream,Xor暗号もおまけ)



TFileStreamを使う場合は一度にファイルを読み込んじゃった方が高速です。
とりあえずXor暗号を例にしてそれを示してみよう。
Xor暗号は暗号化と復号化が同じルーチンでできるので楽です。
0.
procedure TForm1.Button1Click(Sender: TObject);
var
SF,DF:TFileStream;
b:integer;
t:byte;
tm:integer;
begin
if (Opendialog1.Execute)and(Savedialog1.Execute) then
  begin
  tm:=timeGettime;//時間の測定の開始

  SF:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead);
  //変換元のファイルを開く
  DF:=TFileStream.Create(SaveDialog1.FileName,fmCreate or fmOpenWrite);
  //変換後のファイルを作る
  while true do
    begin
    b:=SF.Read(t,sizeof(t));//データの読み込み
    if b=0 then break;//ファイルが空になったので終了
    t:=t xor $68;//暗号化or復号化
    DF.Write(t,sizeof(t));//データの書き込み
    end;
  SF.Free;//ファイルを閉じる
  DF.Free;

  Edit1.Text:=inttostr(timeGettime-tm);//かかった時間の計算
  end;

end;

//350ms(ミリ秒)ほど

なんか遅いのでファイルを一気にメモリ上に読み込んでから変換を行い
それを一気にファイルに書き込んでみます

var
SF,DF:TFileStream;
i:integer;
data,data2,pb,pb2:PByte;
tm,sz:integer;
begin
if (Opendialog1.Execute)and(Savedialog1.Execute) then
  begin
  tm:=timeGettime;//時間の測定の開始
  SF:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead);
  //変換元のファイルを開く
  sz:=SF.Size;
  getmem(data,sz);//メモリの確保
  getmem(data2,sz);
  SF.Read(data^,sz);//データの読み込み
  SF.Free;//ファイルを閉じる

  pb:=data;
  pb2:=data2;

  for i:=0 to sz-1 do
    begin
    pb2^:=pb^ xor $68;//暗号化or復号化
    inc(pb);
    inc(pb2);
    end;


  DF:=TFileStream.Create(SaveDialog1.FileName,fmCreate or fmOpenWrite);
  //変換後のファイルを作る
  DF.Write(data2^,sz);//データの書き込み
  DF.Free;//ファイルを閉じる

  freemem(data);//メモリの開放
  freemem(data2);

  Edit1.Text:=inttostr(timeGettime-tm);//かかった時間の計算
  end;

end;

//10ms以内

比較にならないほど速いですね。
ただし、あまりファイルサイズが大きいとスワップが発生する場合があり
それだとかえって遅くなるという事がありえます。
実際にはファイルを適当なサイズで区切って読み出すという方法が適切です。

という事で一応ソースコードです。
xor.lzh(1.89kbyte)

TextFileはメモリーに一度に読んでしまうと聞いているので
その場合はそれほどの効果は期待できないかもしれません。


上へ
目次へ


GigaHit