2016-08-12 12 views
0

システムバッファリングなしでドライブから直接ファイルを読み込む必要があります。私はここでこのコードを試しましたHow to unload a file from cache?残念なことに、私は "メモリストリームを拡張中にメモリが足りない"というエラーメッセージを受け取ります。私が試したどのファイルでも起こります。後で私は、SrcStream.Sizeが常に値-1を返すことに気付きました。だから、明らかに問題はここにあり、なぜこのようなことが起こっているのでしょうか?"メモリストリーミングを拡張中にメモリが不足しています"

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; 

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

finally 
    DestStream.Free; 
end; 
    finally 
    SrcStream.Free; 
    end; 
end; 
+0

私は、問題はすぐそこにあることがわかります。私の指がどこを指しているのか分かりますか? –

+1

目に見えない指が目に見えないコードを指していますか?うわー、このインターネットのことは本当にクールです。 –

+0

このエラーメッセージは FlagsAndAttributesに表示されません:= FILE_ATTRIBUTE_NORMAL しかし、それは常に FlagsAndAttributesでクラッシュ:= FILE_FLAG_NO_BUFFERING。 –

答えて

3

FILE_FLAG_NO_BUFFERING DelphiのTHandleStreamクラスのすべての機能と互換性がありませんファイルハンドルの使用に関する特別な要件を、配置します。このような要件の主要な点は、すべてのアクセスが整合していることです。これは、ファイルポインタが常にセクタ境界上に配置され、すべての読み書きがセクタサイズの倍数であることを意味する。具体的な障害ポイントは、Sizeプロパティです。

サイズがセクタサイズの倍数ではないファイルを読み込んでいます。あなたが参照する答えは、サイズがセクタサイズの正確な倍数ではないファイルを提示したときに報告するエラーで失敗します。おそらくそのコードの作成者はその問題を認識しておらず、セクタサイズの正確な倍数であるファイルを純粋なチャンスで使用したと思われます。

あなたは、そのサイズあなたはおそらく、このようなファイルハンドルでTHandleStreamを使用することができますが、あなたは注意する必要があります。4096

の正確な倍数である入力ファイルでコードを実行することによって、このすべてを確認することができます。明らかに、Sizeを避けなければなりません。アラインメント要件を遵守しなければなりません。セクタの終わりより前に論理ファイルが終了していることがわかっていても、セクタ全体を読み込む必要があるため、ファイルの最後に読み込むときは注意が必要です。これはReadBufferではなくReadを使用することを意味します。

私の意見では、バッファされていないファイルアクセスを使用する必要がある場合は、ストリーム抽象化が適しているとは思えません。私はWindows APIで直接作業します。

関連する問題