想做一个功能,写1G的空文件,最后一个字节为F。刚才我用MemoryStream做的,发现保存1G的时候死掉了,1k的时候倒是挺好的。请教下。

解决方案 »

  1.   

    改用FileStream,MemoryStream的话会吃你很多内存
      

  2.   

    var
      hFile: THandle;
    begin
            hFile := CreateFile('c:\Data.dat',
                            GENERIC_WRITE,
                            0,
                            Nil,
                            CREATE_ALWAYS,
                            FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED ,
                            0);
            if (hFile = INVALID_HANDLE_VALUE) then begin
                MessageBox(GetActiveWindow(),'创建文件失败!',Nil,MB_OK or MB_ICONERROR);
                Exit;
            end;
    end;
      

  3.   

    const Buffer: AnsiString;
    var 
      hFile: THandle;
      iLen: LongWord;
    begin 
      Buffer := 'F';
      hFile := CreateFile('c:\Data.dat', 
                          GENERIC_WRITE, 
                          0, 
                          Nil, 
                          CREATE_ALWAYS, 
                          FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED , 
                          0); 
      if (hFile = INVALID_HANDLE_VALUE) then begin 
        MessageBox(GetActiveWindow(),'创建文件失败!',Nil,MB_OK or MB_ICONERROR); 
        Exit; 
      end; 
      SetFilePointer(hFile,1024 * 1024 * 1024 - 1,NIL,FILE_CURRENT);
      WriteFile( hFile, Buffer[0], Length(Buffer), iLen, Nil);  SetEndOfFile(hFile);
      CloseHandle(hFile);
    end;
      

  4.   

    var Buffer: AnsiString;
      

  5.   

    unsigned:
            谢谢大哥了,刚才试了一下发现报错:
    [Error] Unit1.pas(45): Element 0 inaccessible - use 'Length' or 'SetLength'
    [Fatal Error] Project1.dpr(5): Could not compile used unit 'Unit1.pas'是不是需要setlength(Buffer,1024 * 1024 * 1024 - 1)?
      

  6.   

    改成这样就行了WriteFile( hFile, Buffer, Length(Buffer), iLen, Nil);
      

  7.   

    僵哥: 我用ultraEdit打开发现最后是一位是空的,没有写'F'进去啊。
      

  8.   

    var
      hFile: THandle;
      iLen: LongWord;
      Buffer: AnsiString;
    begin
      Buffer := 'F';
      hFile := CreateFile('d:\Data.dat',
                          GENERIC_WRITE,
                          0,
                          Nil,
                          CREATE_ALWAYS,
                          FILE_ATTRIBUTE_NORMAL  ,
                          0);
      if (hFile = INVALID_HANDLE_VALUE) then begin
        MessageBox(GetActiveWindow(),'创建文件失败!',Nil,MB_OK or MB_ICONERROR);
        Exit;
      end;
      SetFilePointer(hFile,1024 * 1024 * 1024 - 1,NIL,FILE_BEGIN);
      WriteFile( hFile, Buffer[1], Length(Buffer), iLen, Nil);
      CloseHandle(hFile);
    end;抱歉前面的代码多了 FILE_FLAG_OVERLAPPED 
      

  9.   

    var
      hFile: THandle;
      iLen: LongWord;
      Buffer: AnsiString;  Ovl: OVERLAPPED;begin
      Buffer := 'F';
      FillChar(Ovl, sizeof(Ovl), 0);
      hFile := CreateFile('d:\Data.dat',
                          GENERIC_WRITE,
                          0,
                          Nil,
                          CREATE_ALWAYS,
                          FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED  ,
                          0);
      if (hFile = INVALID_HANDLE_VALUE) then begin
        MessageBox(GetActiveWindow(),'创建文件失败!',Nil,MB_OK or MB_ICONERROR);
        Exit;
      end;
      Ovl.Offset := 1024 * 1024 *1024 -1;
      Ovl.hEvent := CreateEvent(Nil, true, true, Nil);
      WriteFile( hFile, Buffer[1], Length(Buffer), iLen, @Ovl);
      GetOverlappedResult( hFile, Ovl, iLen, true);
      CloseHandle(Ovl.hEvent);
      CloseHandle(hFile);
    end;
      

  10.   

    少分配点儿内存,循环写入。不过这个影响也不算太大,如果内存够用的话不会交换页面文件,基本没多少影响。而且瓶颈也不在这里而是io速度,cache命中率的损失都已经可以忽略不计了
    所以最有效的办法是换个更快的硬盘,或者在大内存机器上往ram disk写
      

  11.   

    不是你想要快就能够快的,为文件分配占用空间和创建一个空文件(里面用#0填充)是两回事,前者只需要有文件分配表当中配置即可,后者是需要进行内容的改写的.下面的代码速度可能会快一点.var
      hFile: THandle;
      iLen: LongWord;
      Buffer: AnsiString;
      Ovl: OVERLAPPED;
      start,end_,pfmfreq: Int64;
    begin
      QueryPerformanceCounter(start);  hFile := CreateFile('d:\Data.dat',
                          GENERIC_WRITE,
                          0,
                          Nil,
                          CREATE_ALWAYS,
                          FILE_ATTRIBUTE_NORMAL or FILE_FLAG_NO_BUFFERING or FILE_FLAG_OVERLAPPED ,
                          0);
      if (hFile = INVALID_HANDLE_VALUE) then begin
        MessageBox(GetActiveWindow(),'创建文件失败!',Nil,MB_OK or MB_ICONERROR);
        Exit;
      end;
      FillChar(Ovl, sizeof(Ovl), 0);
      SetLength(Buffer,512);
      FillChar(Buffer[1], 512, 0);
      Buffer[512] := 'F';
      Ovl.Offset := 1024 * 1024 * 1024 - 512;
      Ovl.hEvent := CreateEvent(Nil, true ,true, Nil);
      WriteFile( hFile, Buffer[1], Length(Buffer), iLen, @Ovl);
      GetOverlappedResult(hFile, Ovl, iLen, true);
      CloseHandle(Ovl.hEvent);
      CloseHandle(hFile);
      QueryPerformanceCounter(end_);
      QueryPerformanceFrequency(pfmfreq);
      ShowMessage(IntToStr(((end_ - start) * 1000 div pfmfreq)));
    end;
      

  12.   

    嗯,应该是磁盘的影响吧,我刚才测试了30秒左右。
    那有没有其他办法,请教僵哥了!
    我看到pps的方式非常快,真有点不可思议。
      

  13.   

    光是分配空间当然快,
    CreateFile
    SetFilePointer
    SetEndOfFile
    CloseHandle
    总共一毫秒就可以完成.
      

  14.   


    // 以前写过的一个小软件有这个功能,不过是c++的,不会该delphi,fileSize单位MB
    // 刚才试了一下光写入1G文件大概30秒左右
    void __fastcall TMakeDummy::MakeFile(const String &fileName, int fileSize)
    {
    int fileH = 0;
    int bufSize = 1024*1024; // 1MB try
    {
    boost::scoped_array<char> buf(new char[bufSize]);
    std::memset(buf.get(), '\0', bufSize); fileH = FileCreate(fileName); for (int i=1; i<=fileSize; i++)
    {
    FileWrite(fileH, buf.get(), bufSize);
    Application->ProcessMessages();
    }
                    // 填充完,把最后一个字节改为0x0F
    }
    catch (...)
    {
    FileClose(fileH);
    throw 0;
    } FileClose(fileH);
    }
      

  15.   

    MemoryStream先读到内存去,你内存大了是吧. 用普通的读写就可以了.
      

  16.   


    你这个还得先在DELPHI里实现C++里智能指针