0

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

我想将较小的文件从较大的文件中提取到等于"smallFile.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));

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

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

什么会导致这些差异?我错在哪里?

4

1 回答 1

0

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

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

   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);

找到startIndex并且endIndex你甚至可以使用你以前的技术,但这样的东西更合适。

然而,这仍然是有问题的,因为:

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

那么该怎么办?

  1. 不要将内存中的文件内容作为字节数组读取。改为使用FileStream
  2. 将 a 包裹StreamReader起来FileStream并使用它来查找开始和结束索引的标记。更好的是,更改您的文件格式,这样您就不需要搜索文本。
  3. 知道startIndexand之后length,使用流函数查找输入流的相关部分并将length字节复制到输出流。
于 2012-05-07T10:42:53.337 回答