如何替换二进制文件中的 unicode 字符串?
How can I replace a unicode string in a binary file?
我一直在尝试让我的程序替换二进制文件中的 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
}
用于检查文件是否包含用户输入的字符串(如果重要)。
这只能在非常有限的情况下起作用。不幸的是,您没有提供足够的关于二进制文件性质的详细信息,让任何人都不知道这是否适用于您的情况。实际上有无穷无尽的二进制文件格式,如果您修改单个字节,至少其中一些会变得无效,如果文件长度发生变化(即插入点之后的数据是不再是预期的位置)。
当然,许多二进制文件也经过加密和/或压缩。在这种情况下,即使您奇迹般地找到了您要查找的文本,它可能实际上并不代表该文本,修改它会使文件无法使用。
综上所述,为了争论起见,我们假设您的场景没有任何这些问题,并且完全可以用一些完全不同的文本完全替换文件中间的一些文本。
请注意,我们还需要对文本编码进行假设。文本可以用多种方式表示,您需要使用正确的编码,不仅是为了找到文本,也是为了确保替换文本有效。为了争论起见,假设您的文本编码为 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 位平台上,您可能会发现需要以较小的块来处理文件。
我一直在尝试让我的程序替换二进制文件中的 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
}
用于检查文件是否包含用户输入的字符串(如果重要)。
这只能在非常有限的情况下起作用。不幸的是,您没有提供足够的关于二进制文件性质的详细信息,让任何人都不知道这是否适用于您的情况。实际上有无穷无尽的二进制文件格式,如果您修改单个字节,至少其中一些会变得无效,如果文件长度发生变化(即插入点之后的数据是不再是预期的位置)。
当然,许多二进制文件也经过加密和/或压缩。在这种情况下,即使您奇迹般地找到了您要查找的文本,它可能实际上并不代表该文本,修改它会使文件无法使用。
综上所述,为了争论起见,我们假设您的场景没有任何这些问题,并且完全可以用一些完全不同的文本完全替换文件中间的一些文本。
请注意,我们还需要对文本编码进行假设。文本可以用多种方式表示,您需要使用正确的编码,不仅是为了找到文本,也是为了确保替换文本有效。为了争论起见,假设您的文本编码为 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 位平台上,您可能会发现需要以较小的块来处理文件。