用 CreateFile 函数创建一个磁盘文件,写文件正常:
hFile = CreateFile(strFileName, GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, ByVal 0&, CREATE_NEW, 0, 0)现需要更新其文件头部分的一个 TLV 对象的 Value 域。从文件起始查找该对象成功(SetFilePointer 和 ReadFile)。     ReadFile hFile, lngTmp, 4, ret, ByVal 0&
    If ret <> 4 Then Exit Function
    
    lngNumber = lngNumber + lngTmp    '这里正常
    
    ret = SetFilePointer(hFile, -4, 0, FILE_CURRENT)    ' ret 得到新的指针,本例 = 2
    ret = WriteFile(hFile, lngNumber, 4, n, ByVal 0&)    '这里出现问题    '注:ret = 0(期望 1), n = 0(期望 4), GetLastError = 0    '如果上面正常或跳过上面的写,执行下面的读
    ret = SetFilePointer(hFile, -4, 0, FILE_CURRENT)    ' ret 得到新的指针,本例 = 2
    ret = ReadFile(hFile, lngTmp, 4, n, ByVal 0&)    '这里出现问题    '注:ret = 1(期望 1), n = 0(期望 4), GetLastError = 0
    '按照 MSDN 的说法,返回值 = 1 且 lpNumberofBytesRead = 0 表示指针超出可读区域。我现在的做法是绕过这一难题:    ret = SetFilePointer(hFile, -4, 0, FILE_CURRENT)
    ret = SetFilePointer(hFile, ret, 0, FILE_BEGIN)
    ret = WriteFile(hFile, lngNumber, 4, n, ByVal 0&)
    '......
    
    ret = SetFilePointer(hFile, -4, 0, FILE_CURRENT)
    ret = SetFilePointer(hFile, ret, 0, FILE_BEGIN)
    ret = ReadFile(hFile, lngTmp, 4, n, ByVal 0&)这样可以正常读写。但是总觉得有点别扭,也奇怪为什么回卷指针后会出现这样的问题。

解决方案 »

  1.   

    你用了 CREATE_NEW 参数,但是上来就要读,好像不一致。
    要随机访问试试加上 FILE_FLAG_RANDOM_ACCESS 标志。还有VB本身就能操作二进制文件,为什么还要API?
      

  2.   

    原来就是用的 Open, Get, Put 语句。但是用户要求文件大小可达 64 G。
      

  3.   

    我通常都用Put , Get 的说
      

  4.   

    加了 FILE_FLAG_RANDOM_ACCESS ,问题依旧。    hFile = CreateFile(strFileName, GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, ByVal 0&, CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0)
      

  5.   

    SetFilePointer怎么声明的?又:你所谓绕过的方式中第一个SetFilePointer是冗余的,它执行是否正确你根本没检查。
      

  6.   

    Public Declare Function SetFilePointer Lib "kernel32" (ByVal hFile As Long, ByVal lDistanceToMove As Long, lpDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As Long不完全是冗余的。因为我不能确定用户文件中该对象的位置,第一个 SetFilePointer 使我得到了当前指针位置,类似 Open 系统中的 Seek 函数,第二个 SetFilePointer 才可以从头偏移。目前发现,如果不将偏移量高位置为 Null 就行了。     ' 找到该对象的 Value 域,读取
         ReadFile hFile, lngTmp, 4, ret, ByVal 0&
        If ret <> 4 Then Exit Function
        
        ' 计算新值
        lngNumber = lngNumber + lngTmp
        
        ret = SetFilePointer(hFile, -4, ByVal 0&, FILE_CURRENT)
        ret = WriteFile(hFile, lngNumber, 4, n, ByVal 0&)
        If n <> 4 Then Exit Function
        
        ret = SetFilePointer(hFile, -4, ByVal 0&, FILE_CURRENT)
        ret = ReadFile(hFile, lngTmp, 4, n, ByVal 0&)
        If n <> 4 Then Exit Function
        
        If lngTmp = lngNumber Then Update_Trace_File_Number_of_Traces_Ex = True大家可以继续讨论,晚一点结贴。
      

  7.   

    虽然不明白怎么用setfilepointer,不过我在老外的网站给找了有关资料,希望可以帮忙楼主。http://www.codeguru.com/vb/controls/vb_file/directory/article.php/c12917__3/
      

  8.   


    你的E分区呢? ^_^我的最大分区才60G。
    160G的硬盘(有点小 ^_^),分了6个分区。
      

  9.   

    明白了,MSDN 说:If lpDistanceToMoveHigh is not NULL, lpDistanceToMoveHigh and lDistanceToMove form a single 64-bit signed value that specifies the distance to move.If lpDistanceToMoveHigh is NULL, lDistanceToMove is a 32-bit signed value. A positive value for lDistanceToMove moves the file pointer forward in the file, and a negative value moves the file pointer back.实际上将 lpDistanceToMoveHigh 置为 ByVal 0& ,就是置为 Null。 不过现在不这样做了:     ' 找到该对象的 Value 域,读取
         n = SetFilePointer(hFile, 0, ByVal 0&, FILE_CURRENT)  
         ReadFile hFile, lngTmp, 4, ret, ByVal 0& 
        If ret  <> 4 Then Exit Function 
         
        ' 计算新值 
        lngNumber = lngNumber + lngTmp 
        Call SetFilePointer(hFile, n, 0, FILE_BEGIN)
        Call WriteFile(hFile, lngNumber, 4, ret, ByVal 0&) 
        If ret  <> 4 Then Exit Function 
         
        Call SetFilePointer(hFile, n, 0, FILE_BEGIN) 
        Call ReadFile(hFile, lngTmp, 4, ret, ByVal 0&) 
        If ret  <> 4 Then Exit Function 
         
        If lngTmp = lngNumber Then Update_Trace_File_Number_of_Traces_Ex = True 谢谢大家的提示。结贴。
      

  10.   

    API中64位的值不多,到真是忘了它通过两个Long传递负数高位也要设置,所以应该是
    ret = SetFilePointer(hFile, -4, -1, FILE_CURRENT)