2009-06-11 10 views
1

誰かがキャッシュからファイルをアンロードする方法を知っていますか? ファイルをディスクに書き込んだ後、そのファイルを読み込みたいと思います。しかし、Windowsは私にキャッシュからファイルを与えています。ファイルをキャッシュからアンロードする方法は?

begin 
... 

{-- Write file --} 
AssignFile(F, FileName); 
Rewrite(F, 1); 
BlockWrite(F, Buf[0], Chunk); 
CloseFile(F);    { FLUSH } 

some code... 
then..... 

{-- Read file --} 
AssignFile(F, FileName); 
Reset(F, 1);                
BlockRead(F, Buf[0], Chunk);  <----------- getting file from cache 
CloseFile(F); 
end; 

- 私は/ドライブの速度を読み書きを決定しようとしています。

+0

をあなたはそれがチャンクを読み込むためにかかる時間の長さを決定しようとしていますか?そうであれば、それはOSであり、おそらくハードウェア(ディスクに内部キャッシュがある場合)機能であるので、キャッシュからの読み取りを防止する簡単な方法がないかもしれません。 –

+0

@Gerry - はい、これは私がやろうとしていることです。私は(物理的な)ディスクキャッシュは、他のいくつかのファイルを読むと簡単にゴミ箱に入れられると思います。これは問題ではありません。 – Ampere

答えて

4

FILE_FLAG_NO_BUFFERINGの使用を実証するために、それはあなたの読書の時間にどのように影響するかをテストするためにいくつかのコード:420メガバイトのサイズのファイルを使用してこのコードを実行する

uses 
    MMSystem; 

function GetTimeForRead(ABuffered: boolean): single; 
const 
    FileToRead = // name of file with maybe 500 MByte size 
var 
    FlagsAndAttributes: DWORD; 
    FileHandle: THandle; 
    SrcStream, DestStream: TStream; 
    Ticks: DWord; 
begin 
    if ABuffered then 
    FlagsAndAttributes := FILE_ATTRIBUTE_NORMAL 
    else 
    FlagsAndAttributes := FILE_FLAG_NO_BUFFERING; 
    FileHandle := CreateFile(FileToRead, GENERIC_READ, FILE_SHARE_READ, nil, 
    OPEN_EXISTING, FlagsAndAttributes, 0); 
    if FileHandle = INVALID_HANDLE_VALUE then begin 
    Result := 0.0; 
    exit; 
    end; 

    SrcStream := THandleStream.Create(FileHandle); 
    try 
    DestStream := TMemoryStream.Create; 
    try 
     DestStream.Size := SrcStream.Size; 

     Sleep(0); 
     Ticks := timeGetTime; 
     DestStream.CopyFrom(SrcStream, SrcStream.Size); 
     Result := 0.001 * (timeGetTime - Ticks); 

    finally 
     DestStream.Free; 
    end; 
    finally 
    SrcStream.Free; 
    end; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    i: integer; 
begin 
    Button1.Enabled := FALSE; 
    try 
    Update; 
    Memo1.Lines.Clear; 
    for i := 1 to 5 do begin 
     Memo1.Lines.Add(Format('Time for buffered file read: %.3f s', 
     [GetTimeForRead(TRUE)])); 
    end; 
    for i := 1 to 5 do begin 
     Memo1.Lines.Add(Format('Time for unbuffered file read: %.3f s', 
     [GetTimeForRead(FALSE)])); 
    end; 
    finally 
    Button1.Enabled := TRUE; 
    end; 
end; 

は私のシステムで提供します:

バッファファイル読み込み時間:3,974秒
バッファファイル読み込み時間:0,922秒
バッファファイル読み込み時間:0,937秒
バッファ時間赤のファイルを読む:0937 S
時間バッファリングされたファイルを読み込むために:0938 S
時間をバッファリングされていないファイルが読み込みのために:3922 S
時間をバッファリングされていないファイルを読み込み用:4,000秒
時間をバッファリングされていないファイルが読み込みのために:4016 S
時間のためにバッファなしのファイルを読む:バッファなしファイルのための4062の
時間を読む:3985 S

+0

ありがとうございました! これは私が必要とする答えだと思います。 ありがとう! – Ampere

+1

あなたのコードでSleep(0)を呼び出すのはなぜですか? – Ampere

+0

まあ、それも削除することができます。コードを実行するには数秒かかることはありませんが、すぐに時間をかけたいコード(外部プロファイラを使用せず、私が使用しているプロファイリングユニットを使用しています)を持っているときは、 "Sleep(0); "完全なタイムスライス内でプロファイルされるコードを実行するために、開始の直前に実行されます。いくつかの連続するコードスニペットの実行時間を数ミリ秒で比較する場合は、間違いなく重要です。 – mghie

4

あなたはファイルをフラッシュするという概念を誤解していると思います。

ファイルをフラッシュしてもディスクキャッシュからファイルが削除されない場合は、ファイルストリームのバッファの内容がファイルに書き込まれます。

(あなたがそれを閉じると、ストリームは自動的に消去されます。ファイルを開くと、そこには何も記述せずに、それをフラッシュするので、これまでどのような効果がありません。)

あなたは、ファイルを読み込むためのFILE_FLAG_NO_BUFFERINGフラグに見ることができ、ドキュメントからは、ハードドライブ上のファイルには影響しないようです。

MSDN: CreateFile

+0

このフラグは、ハードドライブ上のファイルに対しても有効ですが、ディスクドライブ自体のバッファリングを無効にすることはできません。このキャッシュは、最近のドライブでは通常2〜32 MByteの範囲であるため、ファイルが大きいほどドライブキャッシュの影響は小さくなります。 – mghie

+0

私のファイルは100MB以上です。だから私はWindowsが巨大なファイルをキャッシュしていると思います。 – Ampere

+0

私は(物理的な)ディスクキャッシュは、他のいくつかのファイルを読むと簡単にゴミ箱に入れられると思います。これは問題ではありません。 – Ampere

2

ファイルキャッシングので、あなたはDelphiや他の言語を使用するかどうかとは無関係です、OSレベルの操作です。

の理由を教えてください。なぜあなたはキャッシュからの読み取りを確実にしたいのですが、助けが簡単かもしれません。

+0

何人か(mghie)は、私がこれをやりたい理由をすでに理解していました:) – Ampere

0

Chunk変数に無効な値を使用している場合を除き、コードは問題ありません。たとえば、chunk = 0の場合、バッファにデータを読み込まないため、バッファは古い値を保持します。 (これはディスクに書き込んだデータと同じものです)

+0

番号チャンクは約100MBです。 – Ampere

4

Win32 APIを直接使用する必要があります。具体的には、FILE_FLAG_NO_BUFFERINGフラグを指定してCreateFileを直接使用する必要があります。 OSはキャッシュの代わりにディスクから強制的に読み込み、そのファイルのキャッシュもクリアするという副作用があるため、フラグを持たない次の読み込みでもキャッシュに読み込まれますが、ディスクにヒットします次に。

関連する問題