使用WriteFile写文件的时候这些数据实际上是先存在OS的缓存里,要想立刻存入磁盘需要调用FlushFileBuffers。那么使用CopyFile拷贝文件会怎样?

解决方案 »

  1.   

    那在调用完CopyFile后有相关Flush的函数吗,没有找到~~
      

  2.   

    可能直接就写盘了。
    据说windows2000 以后,不但会写盘,
    还要把目标数据同原始数据比对一次,无误,系统才算完成copy.
      

  3.   

    CopyFile提供了回调函数,每传输 64KB 数据回调一次。
    底层具体是怎么一步步操作的就不清楚了
      

  4.   

    先放缓冲才写盘, CopyFile是CreateFile+ReadFile+WriteFile+CloseFile
      

  5.   

    这个是在MSDN上看到的吗?如果是这样最好了。
      

  6.   

    这样的话它并没有调用flush函数,那也就是copy完了并一定就真的写到硬盘上了。
      

  7.   

    CloseHandle的时候, 就都写了. CopyFile结束,肯定是全部写完成的. 如不用CloseHandle, 那就不一定了.
      

  8.   

    所以CreateFile写文件之后,一定要CloseHandle,或者你显示的调用Flush函数, 但这个Flush函数频烦调用, 严重影响性能. 
    如果文件没有写完, 那么写完的数据大小应该是512的倍数(理论上是这样, 感兴趣的可以验证下,我也没验证)  
      

  9.   

    WriteFile 和 CopyFile 的功能和机制大不同
    WriteFile 函数只是简单调用NtWriteFile 和ZwWriteFile ,所以他们有使用FlushFileBuffers的必要
    而CopyFile 要复杂的多,则不需要,看看它们都调用了那些函数,就明白了    WriteFile 调用情况
        kernel32!WriteFile     
     kernel32!_SEH_epilog   
     kernel32!_SEH_prolog   
     ntdll!KiFastSystemCall 
     ntdll!NtWriteFile      
     ntdll!ZwWriteFile      
      CopyFile 调用情况
     kernel32!BaseCopyStream                         
    kernel32!BaseIsThisAConsoleName                 
    kernel32!Basep8BitStringToDynamicUnicodeString  
    kernel32!Basep8BitStringToStaticUnicodeString   
    kernel32!BasepCopyEncryption                    
    kernel32!BasepCopyFileExW                       
    kernel32!BasepProcessNameGrafting               
    kernel32!CloseHandle                            
    kernel32!CopyFileA                              
    kernel32!CopyFileExW                            
    kernel32!CreateFileW                            
    kernel32!SetLastError                           
    kernel32!WriteFile                              
    kernel32!_SEH_epilog                            
    kernel32!_SEH_prolog                            
    kernel32!__security_check_cookie                
    ntdll!KiFastSystemCall                          
    ntdll!NtClose                                   
    ntdll!NtCreateFile                              
    ntdll!NtCreateSection                           
    ntdll!NtMapViewOfSection                        
    ntdll!NtQueryInformationFile                    
    ntdll!NtSetInformationFile                      
    ntdll!NtUnmapViewOfSection                      
    ntdll!NtWriteFile                               
    ntdll!RtlAcquirePebLock                         
    ntdll!RtlAllocateHeap                           
    ntdll!RtlAllocateHeapSlowly                     
    ntdll!RtlAnsiStringToUnicodeString              
    ntdll!RtlCompareMemory                          
    ntdll!RtlCompareMemoryUlong                     
    ntdll!RtlDebugAllocateHeap                      
    ntdll!RtlDebugFreeHeap                          
    ntdll!RtlDetermineDosPathNameType_U             
    ntdll!RtlDosPathNameToNtPathName_U              
    ntdll!RtlDosPathNameToNtPathName_Ustr           
    ntdll!RtlEnterCriticalSection                   
    ntdll!RtlEqualUnicodeString                     
    ntdll!RtlFillMemoryUlong                        
    ntdll!RtlFreeAnsiString                         
    ntdll!RtlFreeHeap                               
    ntdll!RtlFreeHeapSlowly                         
    ntdll!RtlGetFullPathName_Ustr                   
    ntdll!RtlGetNtGlobalFlags                       
    ntdll!RtlInitAnsiString                         
    ntdll!RtlInitString                             
    ntdll!RtlInitUnicodeString                      
    ntdll!RtlInitUnicodeStringEx                    
    ntdll!RtlIsDosDeviceName_U                      
    ntdll!RtlIsDosDeviceName_Ustr                   
    ntdll!RtlLeaveCriticalSection                   
    ntdll!RtlMultiByteToUnicodeN                    
    ntdll!RtlMultiByteToUnicodeSize                 
    ntdll!RtlReleasePebLock                         
    ntdll!RtlUpcaseUnicodeChar                      
    ntdll!RtlpCheckBusyBlockTail                    
    ntdll!RtlpCheckHeapSignature                    
    ntdll!RtlpCoalesce reeBlocks                   
    ntdll!RtlpGetExtraStuffPointer                  
    ntdll!RtlpSysVolAllocate                        
    ntdll!RtlpSysVolFree                            
    ntdll!RtlpUpdateIndexInsertBlock                
    ntdll!RtlpUpdateIndexRemoveBlock                
    ntdll!RtlpValidateCurrentDirectory              
    ntdll!RtlpValidateHeap                          
    ntdll!RtlpValidateHeapEntry                     
    ntdll!RtlpValidateHeapHeaders                   
    ntdll!RtlxAnsiStringToUnicodeSize               
    ntdll!ZwClose                                   
    ntdll!ZwCreateSection                           
    ntdll!ZwMapViewOfSection                        
    ntdll!ZwQueryInformationFile                    
    ntdll!ZwQueryVolumeInformationFile              
    ntdll!ZwSetInformationFile                      
    ntdll!ZwUnmapViewOfSection                      
    ntdll!ZwWriteFile                               
    ntdll!_SEH_epilog                               
    ntdll!_SEH_prolog                               
    ntdll!__security_check_cookie                   
    ntdll!memmove                                   
    ntdll!wcslen                                    
      

  10.   

    WriteFile也不需要FlushFileBuffers, 最后关闭句柄就完事了. 只有在不想关文件句柄又想写完当前文件数据的情况才需要这个. 
    CopyFile就是对CreateFile,WriteFile...这些函数的封装,要进行准备和扫尾工作, 当然用到的函数多了. 
      

  11.   

    Ring3层对文件的操作最终都转到调用NtCreateFile系列函数
      

  12.   

    windbg一下可以得到。
    从copyfile信息看它是做了安全检查,速度优化等方面的处理,里面有MapViewOfSection 等函数。