【问题标题】:How can I replace a unicode string in a binary file?如何替换二进制文件中的 unicode 字符串?
【发布时间】:2015-01-21 08:24:28
【问题描述】:

我一直在尝试让我的程序替换二进制文件中的 unicode。 用户输入要查找的内容,程序会找到并用特定的字符串替换它。

我已经四处搜索,但我找不到任何关于我的细节,我想要的是这样的:

string text = File.ReadAllText(path, Encoding.Unicode);
text = text.Replace(userInput, specificString);
File.WriteAllText(path, text);

但是任何以类似方式工作的东西都应该足够了。 但是,使用它会导致文件更大且无法使用。

我用:

int var = File.ReadAllText(path, Encoding.Unicode).Contains(userInput) ? 1 : 0;
if (var == 1)
{
    //Missing Part
}

用于检查文件是否包含用户输入的字符串,如果重要的话。

【问题讨论】:

  • 题外话,但我不得不问,为什么要创建一个三元运算符来创建第二个比较?
  • 您唯一的问题是您必须读取内存中的整个文件。还是有其他顾虑?
  • 这几乎是不可能的。二进制文件可以通过校验和/哈希来保护。
  • 问题是:使用我现在使用的,它会写入一个由文本组成的全新文件,这不是我想要的。我正在尝试替换单个字符串。
  • @ahpPer 您将不得不重写整个文件。你没有定位任何东西

标签: c# unicode


【解决方案1】:

这只能在非常有限的情况下起作用。不幸的是,您没有提供关于二进制文件性质的足够详细信息,以便任何人知道这是否适用于您的情况。二进制文件格式几乎无穷无尽,如果您修改单个字节,至少其中一些会变为无效,如果文件长度发生变化(即插入点之后的数据是不再是预期的位置)。

当然,许多二进制文件也被加密、压缩或两者兼而有之。在这种情况下,即使您奇迹般地找到了您要查找的文本,它也可能并不真正代表该文本,修改它会使文件无法使用。

说了这么多,为了争论,我们假设你的场景没有任何这些问题,完全可以用一些完全不同的文本完全替换文件中间的一些文本。

请注意,我们还需要对文本编码做出假设。文本可以用多种方式表示,您不仅需要使用正确的编码来查找文本,还需要确保替换文本有效。为了争论,假设您的文本编码为 UTF8。

现在我们拥有了所需的一切:

void ReplaceTextInFile(string fileName, string oldText, string newText)
{
    byte[] fileBytes = File.ReadAllBytes(fileName),
        oldBytes = Encoding.UTF8.GetBytes(oldText),
        newBytes = Encoding.UTF8.GetBytes(newText);

    int index = IndexOfBytes(fileBytes, oldBytes);

    if (index < 0)
    {
        // Text was not found
        return;
    }

    byte[] newFileBytes =
        new byte[fileBytes.Length + newBytes.Length - oldBytes.Length];

    Buffer.BlockCopy(fileBytes, 0, newFileBytes, 0, index);
    Buffer.BlockCopy(newBytes, 0, newFileBytes, index, newBytes.Length);
    Buffer.BlockCopy(fileBytes, index + oldBytes.Length,
        newFileBytes, index + newBytes.Length,
        fileBytes.Length - index - oldBytes.Length);

    File.WriteAllBytes(filename, newFileBytes);
}

int IndexOfBytes(byte[] searchBuffer, byte[] bytesToFind)
{
    for (int i = 0; i < searchBuffer.Length - bytesToFind.Length; i++)
    {
        bool success = true;

        for (int j = 0; j < bytesToFind.Length; j++)
        {
            if (searchBuffer[i + j] != bytesToFind[j])
            {
                success = false;
                break;
            }
        }

        if (success)
        {
            return i;
        }
    }

    return -1;
}

注意事项:

  • 以上内容具有破坏性。您可能只想在文件的副本上运行它,或者更喜欢修改代码,以便它接受一个附加参数,指定应该将修改写入到的 new 文件。
  • 此实现在内存中完成所有操作。这更方便,但如果您要处理大文件,尤其是在 32 位平台上,您可能会发现需要以更小的块处理文件。

【讨论】:

  • 完美,正是我需要的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-30
相关资源
最近更新 更多