C# 从C+;创建的二进制文件中读取Int64值失败+; 我开发了一个C应用程序,从C++程序创建的二进制文件中读取数据,进行项目验证。 下面是C++程序的编码…< /P> // File Name: Ean2an.bin which is created by struct struct EAN2AN_TYPE { __int64 ean:40; // 5 bytes, up to 12 digits __int64 rec_no:24; // 3 bytes rec no in the c_ItemMaster File, up to 16 million records }; // After bind data to struct, wil create the binary file bool CreateBin_EAN2AN_TYPE() { if(mn_RecordCount_EAN2AN_TYPE == 0) return false; FILE *binfile; qsort(mc_EAN2AN_TYPE, mn_RecordCount_EAN2AN_TYPE, sizeof(struct EAN2AN_TYPE), qsort_EAN2AN_TYPE); try { binfile = fopen(ms_Path_EAN2AN_TYPE, "wb"); fwrite(&mc_EAN2AN_TYPE, sizeof(struct EAN2AN_TYPE), mn_RecordCount_EAN2AN_TYPE, binfile); } catch(Exception ^ex) { TaskProgramLibrary::Message::ERR("Create EAN2AN_TYPE.bin fail!\r\n " + ex->Message); } finally { fclose(binfile); mdw_FileSize_EAN2AN_TYPE = FileSize(ms_Path_EAN2AN_TYPE); } return true; }

C# 从C+;创建的二进制文件中读取Int64值失败+; 我开发了一个C应用程序,从C++程序创建的二进制文件中读取数据,进行项目验证。 下面是C++程序的编码…< /P> // File Name: Ean2an.bin which is created by struct struct EAN2AN_TYPE { __int64 ean:40; // 5 bytes, up to 12 digits __int64 rec_no:24; // 3 bytes rec no in the c_ItemMaster File, up to 16 million records }; // After bind data to struct, wil create the binary file bool CreateBin_EAN2AN_TYPE() { if(mn_RecordCount_EAN2AN_TYPE == 0) return false; FILE *binfile; qsort(mc_EAN2AN_TYPE, mn_RecordCount_EAN2AN_TYPE, sizeof(struct EAN2AN_TYPE), qsort_EAN2AN_TYPE); try { binfile = fopen(ms_Path_EAN2AN_TYPE, "wb"); fwrite(&mc_EAN2AN_TYPE, sizeof(struct EAN2AN_TYPE), mn_RecordCount_EAN2AN_TYPE, binfile); } catch(Exception ^ex) { TaskProgramLibrary::Message::ERR("Create EAN2AN_TYPE.bin fail!\r\n " + ex->Message); } finally { fclose(binfile); mdw_FileSize_EAN2AN_TYPE = FileSize(ms_Path_EAN2AN_TYPE); } return true; },c#,binary,windows-ce,C#,Binary,Windows Ce,我尝试使用二进制读取(基于位置)读取数据,并使用位转换器转换为int64或使用Marshal.PtrToStructure,但返回的值不正确。然后我尝试从文件中读取5个字节而不是8个字节,但返回值仍然不正确 Below is the written C# coding //Struct created in C# [StructLayout(LayoutKind.Sequential)] public struct EAN2AN_TYPE {

我尝试使用二进制读取(基于位置)读取数据,并使用位转换器转换为int64或使用Marshal.PtrToStructure,但返回的值不正确。然后我尝试从文件中读取5个字节而不是8个字节,但返回值仍然不正确

Below is the written C# coding
    //Struct created in C#
   [StructLayout(LayoutKind.Sequential)]
        public struct EAN2AN_TYPE
        {
            [MarshalAs(UnmanagedType.I8)]
            public Int64 ean;
            [MarshalAs(UnmanagedType.I8)]
            public Int64 rec_no;
        } 

    //The ways i tried to read in C#
    //1.Read Int64 by Binary 
    private void ReadByBinary()
         {
            using (BinaryReader b = new BinaryReader(_fs))
            {
                while (b.PeekChar() != 0)
                {
                    Int64 x = b.ReadInt64();
                    Console.WriteLine(x.ToString());

                }
            }

        }

   //2.Using Marshal to convert the Intptr to struct's field type
    private object ReadByMarshal(Type iType)
        {
            _oType = iType;// typeof(System.Int64);
            byte[] buffer = new byte[Marshal.SizeOf(_oType)];
            //byte[] buffer = new byte[5];

            object oReturn = null;

            try
            {
                _fs.Read(buffer, 0, buffer.Length);

                GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
                oReturn = Marshal.PtrToStructure(handle.AddrOfPinnedObject(), _oType);
                handle.Free();

                return oReturn;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }


    //3. Use Binary and use bit converter to convert to Int64
     private void ReadByBinaryAndUseBitConverter()
        {
            using (BinaryReader b = new BinaryReader(_fs))
            {
                byte[] x = b.ReadBytes(8);
                Int64 y = BitConverter.ToInt64(x, 0);
                Console.WriteLine(y);

                byte[] x2 = b.ReadBytes(8);
                Int64 y2 = BitConverter.ToInt64(x2,0);
                Console.WriteLine(y2);
            }

        }


    //4. Use Marshal and convert to struct
    public EAN2AN_TYPE  GetStructValue()
        {

            byte[] buffer = new byte[Marshal.SizeOf(typeof(EAN2AN_TYPE)];

            EAN2AN_TYPE oReturn = new EAN2AN_TYPE();

            try
            {
                //if (EOF) return null;

                _fs.Read(buffer, 0, buffer.Length);
                GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
                IntPtr rawDataPtr = handle.AddrOfPinnedObject();

               oReturn = (EAN2AN_TYPE)Marshal.PtrToStructure(rawDataPtr, typeof(EAN2AN_TYPE));

                handle.Free();

                if (_fs.Position >= _fs.Length)
                    Close();

                return oReturn;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
编辑:上载二进制文件的图像

编辑:C#程序读取的前8字节值

编辑器显示的二进制数据

有人知道吗


提前感谢

数据的结尾(如果是一个词的话)可能有问题。如果数据写在大端系统上,读作小端系统,就会遇到这样的问题,反之亦然


另一个问题是,这两个字段实际上被压缩到一个64位值中。您可能需要读取Int64,然后使用位操作来提取这两个字段。所有代码似乎都在通过各种方式读取两个Int64值。

ean
被定义为40位实体,
rec\u no
为24位,使得整个结构仅为64位。您对EAN2AN_类型的定义是128位,因此显然会有问题。我怀疑编写初始代码的人是否明智,但你的工作是找回代码并使用它,所以你要玩你要玩的东西

编辑:更新以使用您指定的数据并考虑Ben的投诉

这里有两种方法可以得到相同的结果。一种是更容易理解的,因为它的动作是分步进行的,另一种是更快和“更正确的”。我将您的示例EAN数据输入到我的输入中,以验证结果

public struct EAN2AN_TYPE
{
    public long ean; // can hold 5 bytes
    public int rec_no; // can hold 3 bytes
}

byte[] incoming = new byte[] { 0x6F, 0x5D, 0x7C, 0xBA, 0xE3, 0x06, 0x07, 0x08 };
内存复制:

using(var stream = new MemoryStream(incoming))
using (var reader = new BinaryReader(stream))
{
    // I leave it to you to get to the data
    stream.Seek(0, SeekOrigin.Begin);

    // get the data, padded to where we need for endianness
    var ean_bytes = new byte[8];
    // read the first 5 bytes
    Buffer.BlockCopy(reader.ReadBytes(5), 0, ean_bytes, 0, 5);
    var rec_no_bytes = new byte[4];
    // read the last 3
    Buffer.BlockCopy(reader.ReadBytes(3), 0, rec_no_bytes, 0, 3);

    var ean2 = new EAN2AN_TYPE();

    // convert
    ean2.ean = BitConverter.ToInt64(ean_bytes, 0);
    ean2.rec_no = BitConverter.ToInt32(rec_no_bytes, 0);
}
位移位:

using (var stream = new MemoryStream(incoming))
using (var reader = new BinaryReader(stream))
{
    // I leave it to you to get to the data
    stream.Seek(0, SeekOrigin.Begin);

    // get the data
    var data = BitConverter.ToUInt64(reader.ReadBytes(8), 0);
    var ean2 = new EAN2AN_TYPE();

    // shift into our data
    ean2.ean = (long)(data & ~0xFFFFFF0000000000);
    ean2.rec_no = (int)(data >> 40);
}

当然,您可以将
EAN2AN_TYPE
设置为一个类,将其输入8个字节,然后使用属性访问器也可以为您执行移动的诡计。如果这必须是双向的,我会这样做(即,您需要将数据放入其中一个结构中以发送回C应用程序)。

谢谢您的回复

<>初始的C++代码是由供应商编写的。我只能通过阅读C++代码来理解。据我所知。。它只是创建二进制文件并写入数据。。 我从代码中找不到任何编码/转换部分

我试图通过代码手动将第一个ean(978086288751)转换为字节[]。 字节[]是111 93 124 186 227 0 0,这与我得到的结果不同

我已经测试了ctacke建议的代码。但我仍然无法得到正确的ean

下面是代码。。(我添加到文件流中以读取二进制文件)

//结果 读取5个字节:17 0 0 ean:17

//我改成

   var ean_bytes = new byte[8];
    Buffer.BlockCopy(reader.ReadBytes(8), 0, ean_bytes, 0, 8);
结果 读取8字节:17 0 0 108 94 5 ean:386865365256241169

很抱歉,我还是一个新用户。。无法发布任何附件。。
希望你能理解我的解释。

恶心,恶心。位移位运算符是在没有位字段的语言中模拟位字段的正确方法。@Ben:同意,但如果您是编程新手,我认为我的第一个示例更清楚地说明了实际发生的情况(是的,perf没有那么好,它会产生垃圾)。您预期的值是多少,您得到的值是多少?您是否使用十六进制编辑器查看了该文件,以查看该文件是否包含正确的值?请查看下面我的答案。我有一个变量叫做“incoming”。向我们展示相同格式的实际数据的8个字节是什么,并告诉use您希望从这8个字节中获得的
ean
rec no
值是什么。在文本编辑器中打开的二进制文件的屏幕截图几乎没有用处。您正在尝试反序列化8个字节。请按文件中的顺序显示这8个字节,仅显示这8个字节,最好是十六进制。这应该是对问题的更新,因为它只会增加清晰度,但不会提供实际答案。是的,我正在更新我的问题。。在我尝试了你的建议代码后的结果。我仍然无法获得正确的ean=(我是否遗漏了编码中的任何内容?请向我显示这8个字节中的确切数据,以及您对结果的预期。Endianness可能在起作用,或者预期数据是在连续字节中,而不是存储为实际数字。从bin文件读取的部分准确结果:Ean编号978086288751 Rec编号162010 Ean编号497185017195 Rec编号196711 Ean编号20000035773 Rec编号421407 Ean编号71881353183 Rec编号517408我无法在此上载任何文件,也无法复制粘贴二进制文件内容(由于大量/0)…如果你不介意的话…我可以通过电子邮件将bin文件发送给你吗?
   var ean_bytes = new byte[8];
    Buffer.BlockCopy(reader.ReadBytes(8), 0, ean_bytes, 0, 8);