none
本机VB的WriteFile函数写入文件如何用.Net读取 RRS feed

  • 问题

  • 本机VB中自定义一个Type,然后声明一个此类型的变量,在用WriteFile写入一个二进制文件后,现在如何用C#.Net或VB.Net读取?
    格子棋
    2010年5月27日 6:44

答案

全部回复

  • 你好 如果你是想读取一个二进制文件的内容 直接通过FileStream类来读取就可以了

    如果是想通过API读取,那么可以调用ReadFile方法


    I see you~http://hi.baidu.com/1987raymondMy Blog~~~
    2010年5月28日 2:20
    版主
  • 哦。。。整个问题是这样的。本机VB里面声明了一个Struct,先对这个Struct变量进行WriteFile,然后再读取这个文件,得到的结果是另一个Struct变量,如何在.Net里面得到这个变量呢?

                  或者说在C#里面也声明一个struct,然后使用API来调用ReadFile方法,这样可行吗?


    格子棋
    2010年5月28日 5:49
  • 你好 你说的WriteFile和我理解的不是一个方法

    你说的是把一个结构体序列化后保存为文件 然后再反序列化为对象吗?

    如果这个序列机制不是二进制序列化或者XML序列化 而是需要调用复杂的逻辑,那么可以像你说的那样通过API调用的方式来实现

    如果你明确的清晰知道保存后的格式 那么可以在c#中直接定义对应的结构 然后反序列化获得


    I see you~http://hi.baidu.com/1987raymondMy Blog~~~
    2010年5月28日 5:55
    版主
  • 呵呵。。。对。。。我说的确实是序列机制,但我不确定是否能够在.Net里面反序列化得到相应的变量。

            看来我有必要试下直接反序列化。


    格子棋
    2010年5月28日 6:43
  • 哦。。。整个问题是这样的。本机VB里面声明了一个Struct,先对这个Struct变量进行WriteFile,然后再读取这个文件,得到的结果是另一个Struct变量,如何在.Net里面得到这个变量呢?

                  或者说在C#里面也声明一个struct,然后使用API来调用ReadFile方法,这样可行吗?


    格子棋


    在C#里也声明同类型的struct或者class,使用Marshal.PtrToStructure方法从字节流中获取对象.

    当然,在C#中定义的struct或class需要一些特性标记.

    2010年5月28日 6:53
  • 补充一点注意下 StructLayoutAttribute http://technet.microsoft.com/zh-tw/sqlserver/system.runtime.interopservices.structlayoutattribute(VS.95).aspx以及FieldOffsetAttribute http://msdn.microsoft.com/zh-cn/system.runtime.interopservices.fieldoffsetattribute(vs.80).aspx

    标记对应的结构体以使得和VB中保存时一致

    [StructLayout(LayoutKind.Explicit)]
    public class SYSTEM_INFO
    {
    [FieldOffset(0)] public ulong OemId;
    [FieldOffset(4)] public ulong PageSize;
    [FieldOffset(16)] public ulong ActiveProcessorMask;
    [FieldOffset(20)] public ulong NumberOfProcessors;
    [FieldOffset(24)] public ulong ProcessorType;
    }
    
    

    I see you~http://hi.baidu.com/1987raymondMy Blog~~~
    • 已标记为答案 pizi xie 2010年6月1日 1:17
    2010年5月28日 7:06
    版主
  • 标记struct以使和VB中保持一致?

            那这么说成员字段名称难道也得一样?

           我刚让别人用WriteFile写了一个二进制文件过来,文件内容似乎除了值以外没别的东西了。


    格子棋
    2010年5月28日 7:17
  • 标记struct以使和VB中保持一致?

            那这么说成员字段名称难道也得一样?

           我刚让别人用WriteFile写了一个二进制文件过来,文件内容似乎除了值以外没别的东西了。


    格子棋

    不用管名称,只管值在内存中的位置和大小.

    比如

    struct A

    {

     int a1;

    char[8] b2;

    }

    struct B

    {

     int b1;

    char[8] a2;

    }

    在内存中的值是等价的.

    2010年5月28日 7:26
  • 在C#里也声明同类型的struct或者class,使用Marshal.PtrToStructure方法从字节流中获取对象.

    当然,在C#中定义的struct或class需要一些特性标记.


    对于Marshal.PtrToStructure方法,我写的如下代码是否有误?

    using (FileStream stream = new FileStream("20100531.min", FileMode.Open))
                {
                    MyObject obj = new MyObject();
                    IntPtr ptr = stream.SafeFileHandle.DangerousGetHandle();
                    Marshal.PtrToStructure(ptr, obj);
                }

    [StructLayout(LayoutKind.Explicit)]
        public class MyObject
        {
            [FieldOffset(0)]
            public UInt32 a;
            [FieldOffset(4)]
            public Single b;
        }

    20100531.min这个文件是在VB里面用WriteFile写的,类型为

    Public Type MyObj
    {
           Long a,
           Single b
    }


    格子棋
    2010年5月28日 8:48
  • byte[] buf = new byte[Marshal.SizeOf(typeof(MyObject))];
    IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buf, 0);

    这样取Ptr ,如果你能使用非托管的API读数据,可以不用该方式.

    long  的话,用int32.

    2010年5月28日 9:12
  • byte[] buf = new byte[Marshal.SizeOf(typeof(MyObject))];
    IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buf, 0);

    这样取Ptr ,如果你能使用非托管的API读数据,可以不用该方式.

    long  的话,用int32.


    呵呵。。。帅哥能否指名代码的意思?       

               莫非要使用Marshal.Copy???


    格子棋
    2010年5月28日 9:29
  • using (FileStream stream = new FileStream("20100531.min", FileMode.Open))
                {
                    MyObject obj = new MyObject();
                    

    byte[] buf = new byte[Marshal.SizeOf(typeof(MyObject))];

    fs.Read(buf,0,buf.Length);

    IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buf, 0);


                    Marshal.PtrToStructure(ptr, obj);
                }

    2010年5月28日 9:32
  • 呵呵。。。帅哥 。。。先谢谢你了。

              byte[] data = new byte[8];
                    stream.Read(data,0,8);

                    IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(data,0);
                    MyObject obj = new MyObject();
                    Marshal.PtrToStructure(ptr, obj);

    我这么做似乎也OK,把指针指向的值复制到对象中?


    格子棋
    2010年5月28日 9:40
  • 是的, Marshal.SizeOf(typeof(MyObject)) 的值就是 8,因为 long 4 位,single 4 位.
    2010年5月28日 9:45
  • 呵呵。。。3Q。。。你的意思是MyObject内存布局的宽度为8个字节。。。
          StructLayout特性标记起了不少作用。


    格子棋
    2010年5月28日 9:59