请教c#读取二进制文件的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了请教c#读取二进制文件的问题相关的知识,希望对你有一定的参考价值。

要做游戏存档修改器
从已知的那个位置起,比如从第6个字节开始,读1个字节数据,然后把这些数据转成文本显示到文本框里
我找了段别人编的代码,运行后无论读什么都只读出System.Byte[]...
请高手给出正确的代码或修改下面的代码
private void button1_Click(object sender, EventArgs e)

string fileName;
byte [] bt= new byte[1];
this.openFileDialog1.ShowDialog();//文件打开路径
fileName = this.openFileDialog1.FileName;//接收文件路径
FileStream fs = new FileStream(fileName, FileMode.Open);
fs.Seek(6, SeekOrigin.Begin);
fs.Read(bt, 0, 1);
fs.Close();

richTextBox1.Text = Convert.ToString(bt);




我用了System.Text.Encoding.ASCII.GetString(bt)或 System.Text.Encoding.UTF8.GetString(bt)
可是...存档文件里的数据是61 66 63,但读出来的却是afc

参考技术A 试试看行不行 string kk = System.Text.Encoding.UTF8.GetString(bt); 或者 string kk = System.Text.Encoding.ASCII.GetString(bt); 至于那个编码具体要看你文件是那个编码

写具体一点
string fileName = "d:\\1.txt";
FileStream fs = new FileStream(fileName, FileMode.Open);
bt = new byte[fs.Length-6]; //定义数组的长度为文件长度-6
fs.Seek(6, SeekOrigin.Begin);//文件流的位置定位到第6个位置
fs.Read(bt, 0, bt.Length); // 读第6个位置后面的所有数据,你的错误可能就在这里。你只读了一个字节
fs.Close();
string str = System.Text.Encoding.ASCII.GetString(bt);本回答被提问者采纳
参考技术B 这样的话,建议你把对象设为可序列化。把对象序列化后保存为文件,读取的时候反序列化就好了。 参考技术C byte数组的你要是用Convert.tostring的话肯定会出那结果的,Byte转换string 你用 Encoding.Default.GetString(); 参考技术D richTextBox1.Text = System.Text.Encoding.ASCII.GetString(bt)

或者

richTextBox1.Text = System.Text.Encoding.UTF8.GetString(bt)

使用 C# 对巨大的二进制文件进行排序

【中文标题】使用 C# 对巨大的二进制文件进行排序【英文标题】:Sorting gigantic binary files with C# 【发布时间】:2011-11-28 03:03:18 【问题描述】:

我有一个大约 400 GB 大小的大文件。由外部封闭系统每天生成。它是一个二进制文件,格式如下:

byte[8]byte[4]byte[n]

其中 n 等于 byte[4] 的 int32 值。

此文件没有分隔符,要读取整个文件,您只需重复直到 EOF。每个“项目”表示为 byte[8]byte[4]byte[n]。

文件看起来像

byte[8]byte[4]byte[n]byte[8]byte[4]byte[n]...EOF

byte[8] 是一个 64 位数字,表示由 .NET Ticks 表示的时间段。我需要对这个文件进行排序,但似乎找不到最快的方法。

目前,我将 Ticks 加载到一个结构中,并将 byte[n] 开始和结束位置并读取到文件的末尾。之后,我按 Ticks 属性对内存中的 List 进行排序,然后打开 BinaryReader 并按 Ticks 顺序查找每个位置,读取 byte[n] 值,然后写入外部文件。

在这个过程的最后,我得到了一个排序的二进制文件,但它需要永远。我正在使用 C# .NET 和一个非常强大的服务器,但磁盘 IO 似乎是个问题。

服务器规格:

2x 2.6 GHz Intel Xeon(Hex-Core with HT)(24 线程) 32GB 内存 500GB RAID 1+0 2TB RAID 5

我浏览了整个互联网,只能找到一个大文件为 1GB 的示例(让我发笑)。

有人有什么建议吗?

【问题讨论】:

我不确定我是否理解您如何在只有 500GB RAID 磁盘的系统上读取一个 400GB 文件并写入另一个已排序的 400GB 文件,但 Greg 的建议听起来不错,尽管我没有亲自处理这么大的文件。 嘿,我还有 2TB RAID 5。 【参考方案1】:

加速这种文件访问的好方法是memory-map the entire file into address space,让操作系统负责从文件中读取它需要的任何位。所以做你现在做的同样的事情,除了从内存中读取而不是使用BinaryReader/seek/read。

你有很多主内存,所以这应该提供相当好的性能(只要你使用 64 位操作系统)。

【讨论】:

感谢您的快速回复! MemoryMappedFile 是否能够处理 400GB 的文件?我是否需要创建不同类型的视图访问器(随机访问与顺序)?再次感谢! :) MemoryMappedFile 应该能够一次性处理所有文件。我已经在 FreeBSD 上使用 Python 完成了这项工作,文件大小为 30 GB,但我完全希望它可以在 Windows 上以您的文件大小正常工作。我不确定访问器之间的区别,但任何一个都可能工作。您将按顺序读取文件一次,然后在排序后以随机顺序读取它。【参考方案2】:

使用归并排序。 它是在线的并且很好地并行化。

http://en.wikipedia.org/wiki/Merge_sort

【讨论】:

【参考方案3】:

如果您可以学习 Erlang 或 Go,它们可能会非常强大并且扩展性非常好,因为您有 24 个线程。利用异步 I/O。合并排序。 由于您有 32GB 的 RAM,请尝试将尽可能多的加载到 RAM 中并在那里对其进行排序,然后再写回磁盘。

【讨论】:

【参考方案4】:

我会分几次这样做。在第一次通过时,我会创建一个刻度列表,然后将它们均匀地分配到许多(数百个?)桶中。如果您提前知道刻度是均匀分布的,则可以跳过此初始通道。在第二次通过时,我会将记录拆分为这几百个大小大致相同的单独文件(这些小得多的文件代表按您想要的顺序排列的刻度组)。然后我会在内存中分别对每个文件进行排序。然后连接文件。

它有点类似于哈希排序(我认为)。

【讨论】:

以上是关于请教c#读取二进制文件的问题的主要内容,如果未能解决你的问题,请参考以下文章

c#二进制文件的写入和读取

在 C# 中使用 QDataStream 读取在 QT 中创建的二进制文件

C# 检查文件的二进制读取器结尾

将二进制文件读取(fread)代码从 MATLAB 转换为 C#

我可以使用 C# 序列化来读取自定义格式的二进制文件吗?

python读取C#写的二进制文件,byte类型unpack