题目要求:生成一个512M大小的文件(文件的内容不管),用什么方法速度最快.----------------------------------------------------
以下是本人的测试:代码1:
var FHandle:THandle;
begin
self.FreeOnTerminate:=True;
self.OnTerminate:=Form1.createSucc;
FHandle:=CreateFile('testfile.wnd',
GENERIC_READ or GENERIC_WRITE , 0, nil, CREATE_ALWAYS,
FILE_FLAG_SEQUENTIAL_SCAN, 0);
if FHandle=INVALID_HANDLE_VALUE then
raise Exception.Create('创建文件失败');
try
SetFilePointer(FHandle,1024*1024*512,nil,FILE_CURRENT);
if not SetEndOfFile(FHandle) then
raise Exception.Create('设置文件大小失败');
finally
CloseHandle(FHandle);
end;
end;
用时:15231毫秒
---------------------------------------------------
代码2:
var FileStream:TFilestream;
buf:array[0..1023] of byte;
i: integer;
Begin
FileStream:=TFilestream.create('testfile.wnd',fmCreate);
fillchar(buf,1024,'0');
for i:=0 to 1024*512 do
FileStream.Write(buf,1024);
FileStream.Free;
{
end;
用时:22332毫秒
--------------------------------------------------------
有兴趣的写出你的代码,并写出使用的时间.
以下是本人的测试:代码1:
var FHandle:THandle;
begin
self.FreeOnTerminate:=True;
self.OnTerminate:=Form1.createSucc;
FHandle:=CreateFile('testfile.wnd',
GENERIC_READ or GENERIC_WRITE , 0, nil, CREATE_ALWAYS,
FILE_FLAG_SEQUENTIAL_SCAN, 0);
if FHandle=INVALID_HANDLE_VALUE then
raise Exception.Create('创建文件失败');
try
SetFilePointer(FHandle,1024*1024*512,nil,FILE_CURRENT);
if not SetEndOfFile(FHandle) then
raise Exception.Create('设置文件大小失败');
finally
CloseHandle(FHandle);
end;
end;
用时:15231毫秒
---------------------------------------------------
代码2:
var FileStream:TFilestream;
buf:array[0..1023] of byte;
i: integer;
Begin
FileStream:=TFilestream.create('testfile.wnd',fmCreate);
fillchar(buf,1024,'0');
for i:=0 to 1024*512 do
FileStream.Write(buf,1024);
FileStream.Free;
{
end;
用时:22332毫秒
--------------------------------------------------------
有兴趣的写出你的代码,并写出使用的时间.
解决方案 »
- 诚心请教Hans-Boehm写的垃圾收集器如何在Delphi中使用?不想引起口水战,鄙视GC者及GC无用论者勿入,拜托
- delphi的16位md5加密算法
- delphi7 listbox 修改了触发的事件是什么事件??
- [求助]如何把禁win键的注册表写入注册表?~~~~
- 谁能给我个GraphicEx控件啊 d7的 就剩20分了 全给了
- 我的图片为什么会失真???
- 一个小问题,Unit not found: 'System.pas' or binary equivalents (DCU,DPU)
- 我的DELPHI7在新建intraweb应用时找不到intraweb选项卡,怎么半?
- 文件的加密问题求助!
- 如何实现在指定ip段内ping扫描上线的主机地址(显示结果)?
- 如何播放VOC格式的文件。
- 如何把现有的cur文件、mp3文件作为资源添加到res文件中?
fh:integer;
begin
fh:=_lcreat('c:\temp',0);
_llseek(fh,512*1024*1024,FILE_BEGIN);
_lwrite(fh,nil,0);
_lclose(fh);
end
------------------
13秒
估计是我的机子速度快吧,估计快不了多少
Begin
FileStream:=TFilestream.create('testfile.wnd',fmCreate);
filestream.size:=512*1024*1024;
FileStream.Free;
{
不是吹牛.....
F: HFILE;
begin
F := FileCreate('C:\Test.tmp', 0);
SetFilePointer(F, 1024 * 1024 * 512, nil, FILE_BEGIN);
SetEndOfFile(F);
FileClose(F);
end;
__int64 myFileSeek (HANDLE hf, __int64 distance, DWORD MoveMethod)
{
LARGE_INTEGER li; li.QuadPart = distance; li.LowPart = SetFilePointer (hf, li.LowPart, &li.HighPart, MoveMethod); if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
{
li.QuadPart = -1;
} return li.QuadPart;
}
Size: Int64;Int64Rec(Size).Lo, @Int64Rec(Size).Hi
其实这段和我的代码1是差不多的.
它生成的速度相当快.
当上面的代码测试之后,似乎都没有办法达到要求,是为什么呢???//
为什么不把你的代码贴出来和大家共享呢.
(HANDLE) hDevice, // handle to a file
FSCTL_SET_SPARSE, // dwIoControlCode
NULL, // lpInBuffer
0, // nInBufferSize
NULL, // lpOutBuffer
0, // nOutBufferSize
(LPDWORD) lpBytesReturned, // number of bytes returned
(LPOVERLAPPED) lpOverlapped // OVERLAPPED structure
);然后设置文件尾就可以了procedure ForExample;
var
F: TFileStream;
Dummy, FSFlags: DWORD;
begin
if GetVolumeInformation('C:\', nil, 0, nil, Dummy, FsFlags, nil, 0)
and ((FSFlags and FILE_SUPPORTS_SPARSE_FILES) <> 0) then
begin
F := TFileStream.Create('C:\test.data', fmCreate);
try
DeviceIoControl(F.Handle, FSCTL_SET_SPARSE, nil, 0, nil, 0, Dummy, nil);
F.Size := 1024*1024*512;
finally
F.Destroy();
end;
end;
end;
F: HFILE;
begin
F := FileCreate('C:\Test.tmp', 0);
SetFilePointer(F, 1024 * 1024 * 512, nil, FILE_BEGIN);
SetEndOfFile(F);
FileClose(F);
end;
--------------------------------------------------------------
这个,速度快
SetEndOfFile(F);这一个函数上。
var
fs: TFileStream;
b: Byte;
timecnt: Integer;
begin
timecnt := GetTickCount();
fs := TFileStream.Create('F:\ABCD.TST', fmCreate);
fs.Position := 512*1024*1024-1;
fs.Write(b, sizeof(b));
fs.Free();
timecnt := GetTickCount() - timecnt;
Application.MessageBox(PChar('Use time: '+inttostr(timecnt)), 'OK', MB_OK);
end;
耗时如下
FAT32: 11607
未压缩的NTFS: 1.492
压缩的NTFS: 0
耗时如下
FAT32: 11607
未压缩的NTFS: 1492
压缩的NTFS: 0
直接访问filesystem当然很快了
var hf:HFile;
begin
hf:= CreateFile('test.tmp', GENERIC_WRITE, FILE_SHARE_WRITE nil,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
SetFilePointer(hf, 1024*1024*512, nil, FILE_BEGIN);
SetEndofFile(hf);
FlushFileBuffers(hf);
end;
用时是100毫秒。
原因是没有加入CloseHandle(hf),如果加入CloseHandle,则又回到上面那个速度了--十几秒钟。
begin
Result := CreateFile(PChar(FileName), GENERIC_WRITE, FILE_SHARE_WRITE, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
SetFilePointer(Result, FileSize, nil, FILE_BEGIN);
SetEndofFile(Result);
FlushFileBuffers(Result);
end;但是当文件句柄关闭的时候(手工调用CloseHandle或者进程退出),还是要很长时间,
因为这个时候会将内存中512M数据传到硬盘上.现在关键之所在,就是如何避免传输?
不过,顺便说一句,如果是作下载程序的话,最终我们还是需要把有用数据传到硬盘的,
所以,我觉得,可以通过上面这个函数返回的句柄操作文件,待下载完毕,再关闭句柄.
我的意思是围绕一个特定大小临时文件,用多线程的方法,将这个文件填充成要下载的文件。
大家可以围绕这个问题讨论,就是有点像FastGet那样就对了。