有人知道如何从缓存中卸载文件吗? 我写了一个文件到磁盘,然后我想读回来。但是,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 :(得分:4)
我认为你误解了刷新文件的概念。
刷新文件不会将其从磁盘缓存中删除,而是会将文件流缓冲区的内容写入文件。
(当你关闭它时,流会自动刷新。打开一个文件并在不写任何内容的情况下将其刷新它对以前没有任何影响。)
您可以查看FILE_FLAG_NO_BUFFERING
标志来读取文件,但从文档中可以看出它对硬盘驱动器上的文件没有影响。
答案 1 :(得分:4)
您需要直接使用Win32 API,特别是使用FILE_FLAG_NO_BUFFERING标志的CreateFile。它强制操作系统从磁盘而不是缓存中读取,并且副作用是它还清除了该文件的缓存,因此没有该标志的下一次读取也会触及磁盘,尽管它会将其读入缓存然后
答案 2 :(得分:4)
一些代码用于演示FILE_FLAG_NO_BUFFERING
的使用并测试它如何影响您的阅读时间:
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;
在我的系统上运行带有420 MB大小文件的代码:
缓冲文件读取时间:3,974 s
缓冲文件读取时间:0,922 s
缓冲文件读取时间:0,937 s
缓冲文件读取时间:0,937 s
缓冲文件读取时间:0,938 s
无缓冲文件读取时间:3,922 s
无缓冲文件读取时间:4,000 s
无缓冲文件读取时间:4,016 s
无缓冲文件读取时间:4,062 s
无缓冲文件读取时间:3,985 s
答案 3 :(得分:2)
文件缓存是一种操作系统级别的操作,因此与您使用Delphi还是其他任何语言无关。
如果您想知道为什么,您希望确保不是从缓存中读取,那么可能更容易提供帮助。
答案 4 :(得分:0)
代码应该没问题,除非您对Chunk变量使用无效值。例如,如果chunk = 0则它不会将任何数据读入缓冲区,因此缓冲区将保持其旧值。 (这可能与您刚写入磁盘的数据相同。)