【问题标题】:How to read binary data at once using BinaryReader in C#?如何在 C# 中使用 BinaryReader 一次读取二进制数据?
【发布时间】:2014-02-24 01:02:43
【问题描述】:

全部

我对处理二进制数据非常陌生。

我正在研究一些来自 MSDN 的代码。

服务器端:

        string fileName = "AppSettings.dat";

        using (BinaryWriter writer = new BinaryWriter(File.Open(fileName, FileMode.Create)))
        {
            writer.Write(1.250F);
            writer.Write(@"c:\Temp");
            writer.Write(10);
            writer.Write(true);
        }

我从服务器收到了二进制文件。

        string clientFile = "AppSettings.dat";

        using (BinaryReader reader = new BinaryReader(File.Open(clientFile, FileMode.Open)))
        {
            float aspectRatio = reader.ReadSingle();
            string tempDirectory = reader.ReadString();
            int autoSaveTime = reader.ReadInt32();
            bool showStatusBar = reader.ReadBoolean();
        }

使用 BinaryWriter 和 BinaryReader 类似乎很容易读写。

但是,这是我的问题。

服务器开发人员离开了公司,不知何故没有人能联系到他。

我不知道他是怎么写信给 BinaryWriter 的。

我的意思是确切的顺序。

在示例中,我必须按顺序阅读阅读器

单读

读取字符串

ReadInt32

ReadBoolean

那我就可以得到正确的结果了。

但在我的情况下,我不知道确切的顺序。

所以,我可以尝试的是如何一次读取所有字符和数字。

喜欢……

string contents = reader.someMethod;

然后内容如下:

1.250F
c:\Temp
10
true

回车可以跳过。

编辑

我已经尝试过 File.ReadAllBytes。

但结果并不是我所期望的……

        byte[] bytes    = System.IO.File.ReadAllBytes(clientFile);
        string contents = Encoding.UTF8.GetString(bytes);

\0\0�?\ac:\Temp\n\0\0\0

【问题讨论】:

  • @Mate 我试过了,结果不是我预期的。

标签: c# binaryreader


【解决方案1】:

下面的代码写入一个二进制文件,然后将其读入字节数组并输出十六进制值。

using (var writer = new BinaryWriter(File.Create("foo.bin")))
{
    writer.Write(1.250F);
    writer.Write(@"c:\Temp");
    writer.Write(10);
    writer.Write(true);
}

var bytes = File.ReadAllBytes("foo.bin");
var text = BitConverter.ToString(bytes);
Console.WriteLine(text);

这是输出:

00-00-A0-3F-07-63-3A-5C-54-65-6D-70-0A-00-00-00-01

解码,我们有:

0000A03f - 4 bytes = 1.250F

接下来是对应于字符串“c:\Temp”的 8 个字节。第一个字节07 是长度。 BinaryWriter 对长度使用 7 位编码方案,因此小于 128 字节的字符串只需要一个长度字节。组成字符串的 7 个字符跟在长度字节后面。

接下来你有四个字节0A000000,也就是整数10。

最后,你得到了值 1,它是布尔值 True。

您应该使用BitConverter.ToString(bytes) 从您的文件中输出数据。然后你可以直接检查字节。

如果您对文件中的内容有所了解,通常可以将其弄明白。字符串很容易挑选出来,您通常可以将它们用作锚来找出它们两侧的内容。如果您了解文件中的内容并且只是想弄清楚文件的写入顺序,则尤其如此。

您实际上并不需要反编译器来确定他写入内容的顺序。您可以使用 ildasm.exe 来检查生成的 MSIL。对BinaryWriter.Write 的函数调用很容易发现,反汇编代码会告诉你它是否在编写字符串、布尔值、整数等。对于一次性的事情,这就是我要走的路。如果我有一份更大的工作需要理解大量代码,我会选择更好的反编译器。

【讨论】:

  • 谢谢吉姆。很有帮助。
  • 顺便问一下,我怎么知道 07 代表 7 位编码方案?因为我有一个句子的第一个字节以 43 开头。
  • 07 不代表 7 位编码方案。 07是长度。如果字符串以字节 43 开头,则字符串长度为 67 个字符(十六进制 43 是十进制的 67)。 “7 位编码”是整数的可变长度编码。见en.wikipedia.org/wiki/Variable-length_quantity
  • @JoshuaSon:还要注意,长度是组成字符串的 字节 的数量,而不是字符的数量。例如,如果字符串写为 16 位 Unicode,则 1 个字符的字符串将占用 2 个字节。有关长度编码方案的更详细说明,另请参阅 informit.com/guides/content.aspx?g=dotnet&seqNum=701
  • 嗨@JimMischel 你能帮我解决这个问题吗:stackoverflow.com/questions/24448304/…
【解决方案2】:

我担心不知道正确的顺序;那么你将很难解决这个问题。

我建议使用 .net 反编译器来阅读他的代码。我假设代码归您的公司所有,所以这样做可能没有错。

RedGates reflector 和 Resharper 都具有将 .net 程序集反编译为 C# 的功能。

还有一个来自 Telerik 的名为“dotPeek”的免费软件,据我所知它非常好,但我自己没有使用过。

本质上,您只需运行程序并为其提供程序集,然后您就可以浏览源代码,只要它没有被混淆即可;但即便如此 - 有些操作无法完全混淆,例如 binaryWriter.Write,因为它们必须以特定顺序发生。

如果这不是您需要的,请尝试澄清您的问题!

希望这会有所帮助。

【讨论】:

  • 我只是想确保没有办法满足我的问题。但吉姆建议如何去做,你提到“工作非常困难”。也感谢您的回答。
猜你喜欢
  • 2021-03-29
  • 1970-01-01
  • 1970-01-01
  • 2021-04-16
  • 1970-01-01
  • 1970-01-01
  • 2012-05-05
  • 1970-01-01
  • 2012-08-06
相关资源
最近更新 更多