none
FileStreamとFileStream.FileSafeHandleを使ったAPIの混在 RRS feed

  • 質問

  • 現在以下のサンプルコードがあります。

    using System;
    using System.IO;
    using System.Runtime.InteropServices;
    using Microsoft.Win32.SafeHandles;
    unsafe static class Class1 {
        [DllImport("kernel32",SetLastError=true)]
        static extern Boolean WriteFile(this SafeFileHandle hFile,void* lpBuffer,UInt32 nNumberOfBytesToWrite,out UInt32 pNumberOfBytesWritten,void* lpOverlapped);
        [DllImport("kernel32",SetLastError=true)]
        static extern Boolean ReadFile(this SafeFileHandle hFile,void* lpBuffer,UInt32 nNumberOfBytesToWrite,out UInt32 pNumberOfBytesWritten,void* lpOverlapped);
        static void Main() {
            var f=new FileStream("B.txt",FileMode.Create,FileAccess.ReadWrite);
            var w=new BinaryWriter(f);
            var b=stackalloc byte[1000];
            for(var a=0;a<10000;a++) {
                uint by;
                f.SafeFileHandle.WriteFile(b,1000,out by,null);
                w.Write("ABCDEFG");
            }
            f.Close();
        }
    }

    やりたいことはFileStreamで開いたファイルに対してInt64やStringを書き込むのにBinaryWriterを使うと便利なので使っています。
    そしてアンセーフメモリでかつ巨大なメモリを一気に書き込むメソッドが.NETにはありませんでした。
    そこでAPIのWriteFileを使って書き込みたいです。
    しかし、このループ途中のWirteFileでIOExceptionエラーが出てしまいます。内容は、

    OS ハンドルの位置が FileStream が予期していた位置ではありませんでした。FileStream 内と Win32 コード内または別の FileStream 内で 1 つのハンドルを同時に使用しないでください。データが失われる可能性があります。

    というものです。
    赤字の目的が達成できればかまいません。他の方法や回避方法はないでしょうか?
    2008年6月28日 23:57