簡體   English   中英

C ++中是否有BinaryReader來讀取從C#中的BinaryWriter寫入的數據?

[英]Is there a BinaryReader in C++ to read data written from a BinaryWriter in C#?

我已經用C#中的BinaryWriter將幾個int,char []等寫入了數據文件。 使用BinaryReader用C#讀回文件,我可以完美地重新創建文件的所有部分。

但是,嘗試用C ++讀回它們會產生一些可怕的結果。 我正在使用fstream嘗試讀回數據,但數據未正確讀入。 在C ++中,我使用ios::in|ios::binary|ios::ate設置了一個fstream,並使用seekg來定位我的位置。 然后,我讀取接下來的四個字節,它們被寫為整數“ 16”(並正確地讀入C#)。 在C ++中,它讀為1244780(不是我檢查過的內存地址)。 為什么會這樣呢? C ++中有與BinaryReader等效的東西嗎? 我注意到它在msdn上提到,但是對我來說,這是Visual C ++,而intellisense甚至看起來都不像c ++。

編寫文件的示例代碼(C#):

    public static void OpenFile(string filename)
    {
        fs = new FileStream(filename, FileMode.Create);
        w = new BinaryWriter(fs);

    }

    public static void WriteHeader()
    {
        w.Write('A');
        w.Write('B');
    }

    public static byte[] RawSerialize(object structure)
    {
        Int32 size = Marshal.SizeOf(structure);
        IntPtr buffer = Marshal.AllocHGlobal(size);
        Marshal.StructureToPtr(structure, buffer, true);
        byte[] data = new byte[size];
        Marshal.Copy(buffer, data, 0, size);
        Marshal.FreeHGlobal(buffer);
        return data;
    }

    public static void WriteToFile(Structures.SomeData data)
    {
        byte[] buffer = Serializer.RawSerialize(data);
        w.Write(buffer);
    }

我不確定如何顯示數據文件。

讀回數據的示例(C#):

        BinaryReader reader = new BinaryReader(new FileStream("C://chris.dat", FileMode.Open));
        char[] a = new char[2];
        a = reader.ReadChars(2);
        Int32 numberoffiles;
        numberoffiles = reader.ReadInt32();
        Console.Write("Reading: ");
        Console.WriteLine(a);
        Console.Write("NumberOfFiles: ");
        Console.WriteLine(numberoffiles);

我想在c ++中執行此操作。 初始嘗試(以第一個整數失敗):

 fstream fin("C://datafile.dat", ios::in|ios::binary|ios::ate);
 char *memblock = 0;
 int size;
 size = 0;
 if (fin.is_open())
 {
  size = static_cast<int>(fin.tellg());
  memblock = new char[static_cast<int>(size+1)];
  memset(memblock, 0, static_cast<int>(size + 1));

  fin.seekg(0, ios::beg);
  fin.read(memblock, size);
  fin.close();
  if(!strncmp("AB", memblock, 2)){ 
   printf("test. This works."); 
  }
  fin.seekg(2); //read the stream starting from after the second byte.
  int i;
  fin >> i;

編輯:看來,無論我使用“ seekg”到什么位置,我都會收到完全相同的值。

您意識到在C#中char是16位,而不是在C中通常是8位。這是因為C#中的char被設計為處理Unicode文本而不是原始數據。 因此,使用BinaryWriter編寫字符將導致寫入Unicode而不是原始字節。

這可能導致您錯誤地計算了整數的偏移量。 我建議您在十六進制編輯器中查看文件,如果無法解決問題,請在此處發布文件和代碼。

編輯1
關於您的C ++代碼,請勿使用>>運算符從二進制流中讀取。 將read()與要讀取的int的地址一起使用。

int i;
fin.read((char*)&i, sizeof(int));

編輯2
從關閉的流中讀取也將導致未定義的行為。 您不能調用fin.close(),然后仍然希望能夠從中讀取。

這可能與問題無關,但...

創建BinaryWriter時,默認情況下是使用UTF-8編寫char 這意味着它們中的一些可能會超過一個字節,從而使您的查找工作中斷。

您可以通過使用2參數構造函數指定編碼來避免這種情況。 System.Text.ASCIIEncoding的實例與默認情況下C / C ++使用的實例相同。

如果有幫助,我會在這里介紹BinaryWriter如何寫入數據。

已經有一段時間了,但我會引用它,希望它是准確的:

  • Int16被寫為2個字節並被填充。
  • Int32編寫為Little Endian,零填充
  • 浮點數更為復雜:它需要一個浮點數並對其進行解引用,從而獲得內存地址的內容(為十六進制)

您的C ++代碼段中有很多錯誤。 您不應將二進制閱讀與格式化閱讀混合使用:

  // The file is closed after this line. It is WRONG to read from a closed file.
  fin.close();

  if(!strncmp("AB", memblock, 2)){ 
   printf("test. This works."); 
  }

  fin.seekg(2); // You are moving the "get pointer" of a closed file
  int i;

  // Even if the file is opened, you should not mix formatted reading
  // with binary reading. ">>" is just an operator for reading formatted data.
  // In other words, it is for reading "text" and converting it to a 
  // variable of a specific data type.
  fin >> i;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM