【问题标题】:Extracting a binary file from other file encoding\conversion mistake从其他文件编码\转换错误中提取二进制文件
【发布时间】:2012-05-07 10:39:53
【问题描述】:

我有两个二进制文件,"bigFile.bin""smallFile.bin"
"bigFile.bin" 包含 "smallFile.bin"
以无与伦比的方式打开它证实了这一点。

我想将较小的文件从较大的文件中提取到一个等于"smallFile.bin"的“result.bin”中。
我有两个关键字——一个用于起始位置(“Section”),一个用于结束位置(“Man”);

我尝试了以下方法:

   byte[] bigFile = File.ReadAllBytes("bigFile.bin");
   UTF8Encoding enc = new UTF8Encoding();
   string text =  enc.GetString(bigFile);

   int startIndex = text.IndexOf("Section");
   int endIndex = text.IndexOf("Man");

   string smallFile = text.Substring(startIndex, endIndex - startIndex);

   File.WriteAllBytes("result.bin",enc.GetBytes(smallFile));

我尝试将结果文件与 Beyond compare 中的原始小文件进行比较,它显示了十六进制表示比较。
没有字节是相等的 - 但有些不是。

例如,在新文件中我有84,但在旧文件中我有EF BF BD 序列。

是什么导致了这些差异?我哪里看错了?

【问题讨论】:

    标签: c# file encoding byte type-conversion


    【解决方案1】:

    由于您使用的是二进制文件,因此不应使用与文本相关的功能(包括编码等)。改为使用与字节相关的方法。

    您当前的代码可以通过如下方式转换为工作:

       byte[] bigFile = File.ReadAllBytes("bigFile.bin");
    
       int startIndex = /* assume we somehow know this */
       int endIndex = /* assume we somehow know this */
    
       var length = endIndex - startIndex;
       var smallFile = new byte[length];
       Array.Copy(bigFile, startIndex, smallFile, 0, length);
       File.WriteAllBytes("result.bin", smallFile);
    

    要找到startIndexendIndex,您甚至可以使用以前的技术,但像this 这样的方法会更合适。

    但是这仍然会有问题,因为:

    1. 将二进制数据和“文本”填充到同一个文件中会使事情复杂化
    2. 这里仍有很多不必要的复制;您应该将输入作为 Stream 而不是字节数组
    3. 比不必要的复制更糟糕的是,任何非流解决方案要么需要像上面那样将所有输入文件加载到内存中(浪费),要么非常复杂地编写代码

    那么,该怎么办?

    1. 不要将内存中的文件内容作为字节数组读取。请改用FileStream
    2. StreamReader 包裹在FileStream 周围,并使用它来查找开始和结束索引的标记。更好的是,更改您的文件格式,这样您就不需要搜索文本了。
    3. 了解startIndexlength 后,使用流函数查找输入流的相关部分并将length 字节复制到输出流。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-13
      • 2014-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多