【问题标题】:C# Read and replace binary data in text fileC#读取和替换文本文件中的二进制数据
【发布时间】:2011-06-28 19:24:29
【问题描述】:

我有一个包含文本数据和二进制数据的文件。这可能不是一个好主意,但我对此无能为力。 我知道二进制数据的结束和开始位置。

在这些位置之间读取二进制数据的最佳方法是什么,从中生成一个 Base64 字符串,然后将其写回原来的位置。

编辑:Base64 编码的字符串与二进制数据的长度不同,因此我可能必须将 Base64 字符串填充到二进制数据长度。

【问题讨论】:

  • 您的 base64 字符串保证比二进制数据大 (4/3)
  • 嗯,好的。这是一件好事。谢谢
  • Base64 已经变大了——你不能把它填满...
  • 我想进一步了解您为什么要这样做。我怀疑您正在寻求一种实施错误解决方案的方法。
  • @Jeffrey,我需要这样做的原因是我们收到了一个包含一些数据的文件。为了使它对我们的应用程序可读,我必须将二进制字段更改为 base64 字符串。

标签: c# binary


【解决方案1】:
int binaryStart = 100;
int binaryEnd = 150;

//buffer to copy the remaining data to it and insert it after inserting the base64string
byte[] dataTailBuffer = null;

string base64String = null;

//get the binary data and convert it to base64string
using (System.IO.Stream fileStream = new FileStream(@"c:\Test Soap", FileMode.Open, FileAccess.Read))
{
    using (System.IO.BinaryReader reader = new BinaryReader(fileStream))
    {
        reader.BaseStream.Seek(binaryStart, SeekOrigin.Begin);

        var buffer = new byte[binaryEnd - binaryStart];

        reader.Read(buffer, 0, buffer.Length);

        base64String = Convert.ToBase64String(buffer);

        if (reader.BaseStream.Position < reader.BaseStream.Length - 1)
        {
            dataTailBuffer = new byte[reader.BaseStream.Length - reader.BaseStream.Position];

            reader.Read(dataTailBuffer, 0, dataTailBuffer.Length);
        }
    }
}

//write the new base64string at specifid location.
using (System.IO.Stream fileStream = new FileStream(@"C:\test soap", FileMode.Open, FileAccess.Write))
{
    using (System.IO.BinaryWriter writer = new BinaryWriter(fileStream))
    {
        writer.Seek(binaryStart, SeekOrigin.Begin);

        writer.Write(base64String);//writer.Write(Convert.FromBase64String(base64String));

        if (dataTailBuffer != null)
        {
            writer.Write(dataTailBuffer, 0, dataTailBuffer.Length);
        }
    }
}

【讨论】:

  • 是的,这对阅读部分进行了排序。我正在努力将 base64 字符串写回文件部分。
  • @hs2d:答案已更新。如果您发现任何问题,请发表评论。
  • @Jalal:看起来没问题,但是你忘记了base64字符串比原始二进制数据大并且二进制块后数据更多的问题。
  • @hs2d:如果是这样的话。我们可以将结束位置之后的数据保存到缓冲区中,并在写入 base64String 之后再次在文件末尾插入该数据。
  • 只是在测试代码,我在这一行遇到异常:using (System.IO.Stream fileStream = new FileStream(@"your file path", FileMode.Open | FileMode.Append)) Exeption:Enum value was out of legal range. Parameter name: mode
【解决方案2】:

您需要使用 FileStream 对象,以及 Read(byte[], int, int) 和 Write(byte[], int, int) 方法。

虽然关于 base64 大于二进制的观点是有效的 - 您实际上需要获取超出要替换的端点的数据,存储它,用新数据写入文件,然后写出完成后存储的数据。

我相信您不会尝试修改 exe 文件以在此处编写病毒... ;)

【讨论】:

  • 但是现在当我有几个二进制块一个接一个并且它们都需要转换为单独的 base64 字符串时,这是不可能的,因为长度会改变,我的位置不会再准确了?
  • 就像我说的那样,您需要首先确定要替换的终点,然后捕获除此之外的所有内容 - 然后您将开始以新格式编写输出而不考虑到前面的位置,最后在完成更改后附加原始结束数据。当然,文件大小会发生变化 - 但从二进制到 base 64 意味着你无法避免不切掉一些东西。
【解决方案3】:

显然,用 base-64 代替二进制数据是行不通的,因为 base-64 会更长。所以问题是,你需要这样做是为了什么?

我推测你已经继承了这种糟糕的二进制文件格式,并且你想使用文本编辑器来编辑这个二进制文件的文本部分。如果是这种情况,那么您可能需要更强大的往返二进制到文本到二进制转换。

我建议对二进制部分使用 base-64,但文件的其余部分应使用 XML 或其他易于解析和解释的格式进行包装。 XML 很好,因为它的解析器已经在系统中可用。

<mydoc>
    <t>Original text</t>
    <b fieldId="1">base-64 binary</b>
    <t>Hello, world!</t>
    <b fieldId="2">928h982hr98h2984hf</b>
</mydoc>

此文件可以根据您的规范轻松创建,并且可以在任何文本编辑器中轻松编辑。然后可以将文件转换回原始格式。如果任何文本侵入二进制字段,则可以将其截断。同样,太短的文本可以用空格填充。

【讨论】:

  • 实际上,我试图将二进制文件转换为 base64 的软件完全符合您的建议。 (:
猜你喜欢
  • 2023-03-13
  • 2019-04-24
  • 1970-01-01
  • 2011-11-22
  • 2019-04-04
  • 2015-04-27
  • 2011-10-01
  • 2017-10-01
  • 2011-09-03
相关资源
最近更新 更多