0

我正在使用 c# 中的 p/invoke 直接写入本地 HD。驱动器已格式化,但不包含任何数据。我要做的就是将 512 个字节的 0 写入驱动器,直到驱动器完全装满。

编码:

for (double idx = 0; idx < TotalSectors; idx++)
    {
        File.Write(writeBuffer, (uint)writeBuffer.Length);  // write the buffer
        int val = pos += (int.Parse(BPS.ToString()) * int.Parse(idx.ToString()));
        File.MoveFilePointer(val);
        Application.DoEvents();
    }

正如你所看到的,只是迭代这个过程,直到所有扇区都被写入。但是,由于某种原因,经过 8 次迭代后,我收到“拒绝访问”错误。

有任何想法吗?

编辑 感谢 Xanatos - 愚蠢的文件位置更新已得到修复。但是,File.MoveFilePointer() 方法需要一个 int。所以我目前正在将 val 转换为(int)。该方法现在迭代 14 次,然后抛出“拒绝访问”异常。

编辑 2 借用代码

write 方法如下所示:

 public uint Write(byte[] buffer, uint cbToWrite)
    {
        // returns bytes read
        uint cbThatWereWritten = 0;
        if (!WriteFile(_hFile, buffer, cbToWrite,
         ref cbThatWereWritten, IntPtr.Zero))
            ThrowLastWin32Err();
        return cbThatWereWritten;
    }

File.MoveFilePointer 方法如下所示:

public void MoveFilePointer(int cbToMove,
     MoveMethod fMoveMethod)
    {
        if (_hFile != null)
            if (SetFilePointer(_hFile, cbToMove, IntPtr.Zero,
             fMoveMethod) == INVALID_SET_FILE_POINTER)
                ThrowLastWin32Err();
    }
4

1 回答 1

3
int bps = ... // Use int!
long TotalSectors = ... // use long!
long pos = 0; // use long!

for (long idx = 0; idx < TotalSectors; idx++)
{
    File.Write(writeBuffer, (uint)writeBuffer.Length);  // write the buffer
    pos += bps;
    // File.MoveFilePointer(pos); // Useless, the file pointer will be moved
                                  // by the File.Write
    Application.DoEvents();
}

完毕!你增长pos太多了!

val = pos += (int.Parse(BPS.ToString()) * int.Parse(idx.ToString()));

忽略val,并忽略Parse(...ToString)它:

pos += BPS * idx;

所以

idx = 0, pos += 0 (pos = 0), // here it's already wrong! you are initializing twice 
                             // the same sector!
idx = 1, pos += 1 * 512 (pos = 512), 
idx = 2, pos += 2 * 512 (pos = 1536) WRONG!

作为旁注,在 .net 中,along是 64 位,对于硬盘的扇区数或大小来说足够大。

于 2013-08-16T07:19:24.147 回答