带起点的SetFilePointer位于EOF

时间:2014-05-22 13:40:20

标签: winapi pinvoke windows-ce

尝试提高旧MC3090设备(Windows CE 5.0)上的文件写入性能我去了WinAPI调用。我必须多次打开文件并附加数据,因此每次使用CreateFile函数创建文件句柄时,请寻找结尾并写入数据。
问题是,winapi并不想寻求最终目标。

这是我的测试示例。

常量:

private const uint GENERIC_WRITE = 0x40000000;
private const uint OPEN_ALWAYS = 4;
private const uint EMOVE_METHOD_END = 2;

功能导入:

[System.Runtime.InteropServices.DllImport("coredll.dll", SetLastError = true)]
static extern unsafe IntPtr CreateFile
(
    string FileName,          // file name
    uint DesiredAccess,       // access mode
    uint ShareMode,           // share mode
    uint SecurityAttributes,  // Security Attributes
    uint CreationDisposition, // how to create
    uint FlagsAndAttributes,  // file attributes
    int hTemplateFile         // handle to template file
);
[System.Runtime.InteropServices.DllImport("coredll.dll", SetLastError = true)]
static extern unsafe bool WriteFile
(
    IntPtr handle,             // handle to file
    void* pBuffer,             // data buffer
    int NumberOfBytesToWrite,  // Number of bytes to write.
    int* pNumberOfBytesWritten,// Number of bytes that were written..
    int Overlapped             // Overlapped buffer which is used for async I/O.  Not used here.
);
[System.Runtime.InteropServices.DllImport("coredll.dll", SetLastError = true)]
static extern unsafe uint SetFilePointer
(
   IntPtr hFile,
   long lDistanceToMove,
   int* lpDistanceToMoveHigh,
   uint dwMoveMethod
);
[System.Runtime.InteropServices.DllImport("coredll.dll", SetLastError = true)]
static extern unsafe bool CloseHandle
(
   System.IntPtr hObject
);

控制台程序Main方法:

    static unsafe void Main(string[] args)
    {
        if (File.Exists("\\storage card\\native.bin"))
            File.Delete("\\storage card\\native.bin");
        var random = new Random();
        var i = 0;
        while (i++ < 3)
        {
            Console.WriteLine("Iteration #" + i);
            var buf = new byte[500000];
            random.NextBytes(buf);

            var gchBuf = GCHandle.Alloc(buf, GCHandleType.Pinned);
            gchBuf.AddrOfPinnedObject();
            var pbuf = gchBuf.AddrOfPinnedObject().ToPointer();

            var pHandle = CreateFile("\\storage card\\native.bin", GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0);
            Console.WriteLine("Open Error - " + Marshal.GetLastWin32Error());

            var newpos = SetFilePointer(pHandle, 0, null, EMOVE_METHOD_END);

            Console.WriteLine("New position - " + newpos);
            Console.WriteLine("Pos Error - " + Marshal.GetLastWin32Error());

            int numberOfBytesWritten;
            WriteFile(pHandle, pbuf, 500000, &numberOfBytesWritten, 0);

            Console.WriteLine("Written - " + numberOfBytesWritten);
            Console.WriteLine("Write Error - " + Marshal.GetLastWin32Error());

            CloseHandle(pHandle);
        }

        Console.ReadLine();
    }

控制台输出:

Iteration #1
Open Error - 2       // ?????
New position - 0
Pos Error - 0
Written - 500000
Write Error - 87      // ?
Result file size - 500000
Iteration #2
Open Error - 183
New position - 0
Pos Error - 0
Written - 500000
Write Error - 50      // ?
Result file size - 500000
Iteration #3
Open Error - 183
New position - 0
Pos Error - 0
Written - 500000
Write Error - 50      // ?
Result file size - 500000

第三次之后的任何迭代都是一样的。
所以,我不了解以下影响:

  1. 第一个CreateFile调用返回2(ERROR_FILE_NOT_FOUND)。在@RemyLebeau评论后,我希望代码为0。
  2. WriteFile调用结果ERROR_NOT_SUPPORTED和ERROR_INVALID_PARAMETER,但文件被写入。此外,我可以检查它的内容,它等于缓冲内容。
  3. SetFilePointer不会失败,但不会改变位置。

0 个答案:

没有答案