21

所以这是交易:我正在尝试打开一个文件(从字节),将其转换为字符串,这样我就可以在标题中弄乱一些元数据,将其转换回字节,然后保存它。我现在遇到的问题是这段代码。当我将来回转换(但未修改)的字符串与原始字节数组进行比较时,它是不相等的。我怎样才能使这项工作?

public static byte[] StringToByteArray(string str)
{
    UTF8Encoding encoding = new UTF8Encoding();
    return encoding.GetBytes(str);
}

public string ByteArrayToString(byte[] input)
{
    UTF8Encoding enc = new UTF8Encoding();
    string str = enc.GetString(input);
    return str;
}

以下是我比较它们的方式。

byte[] fileData = GetBinaryData(filesindir[0], Convert.ToInt32(fi.Length));
string fileDataString = ByteArrayToString(fileData);
byte[] recapturedBytes = StringToByteArray(fileDataString);
Response.Write((fileData == recapturedBytes));

我确定它是 UTF-8,使用:

StreamReader sr = new StreamReader(filesindir[0]);
Response.Write(sr.CurrentEncoding);

它返回“System.Text.UTF8Encoding”。

4

4 回答 4

16

尝试Encoding为您提供各种编码实例的类上的静态函数。您不需要实例化Encoding只是来转换为/从字节数组。你如何比较代码中的字符串?

编辑

您正在比较数组,而不是字符串。它们是不相等的,因为它们引用了两个不同的数组;使用==运算符只会比较它们的引用,而不是它们的值。您需要检查数组的每个元素以确定它们是否等效。

public bool CompareByteArrays(byte[] lValue, byte[] rValue)
{
    if(lValue == rValue) return true; // referentially equal
    if(lValue == null || rValue == null) return false; // one is null, the other is not
    if(lValue.Length != rValue.Length) return false; // different lengths

    for(int i = 0; i < lValue.Length; i++)
    {
        if(lValue[i] != rValue[i]) return false;
    }

    return true;
}
于 2009-09-14T15:38:04.083 回答
7

当您有原始字节(8 位可能不可打印的字符)并希望将它们作为 .NET 字符串进行操作并将它们转换回字节时,您可以使用

Encoding.GetEncoding(1252)

而不是 UTF8Encoding。该编码可以获取任何 8 位值并将其转换为 .NET 16 位字符,然后再转换回来,而不会丢失任何信息。

在您上面描述的特定情况下,使用二进制文件,您将无法“弄乱标头中的元数据”并让事情正常工作,除非您弄乱的数据的长度没有改变。例如,如果标题包含

{any}{any}ABC{any}{any}

并且您想将 ABC 更改为 DEF,这应该可以按您的意愿工作。但是,如果您想将 ABC 更改为 WXYZ,则必须覆盖“C”后面的字节,否则您将(本质上)将所有内容向右移动一个字节。在典型的二进制文件中,这会使事情变得非常混乱。

如果“ABC”之后的字节是空格或空字符,则写入更大的替换数据不会造成麻烦的可能性更大——但你仍然不能在 .NET 字符串中用 WXYZ 替换 ABC,使其更长——你会必须用 WXYZ 替换 ABC{whatever_follows_it}。鉴于此,您可能会发现将数据保留为字节并一次写入一个字节的替换数据更容易。

于 2011-12-22T16:59:38.530 回答
5

由于 .NET 字符串使用 Unicode 字符串这一事实,您不能再像人们在 C 中那样做。在大多数情况下,您甚至不应该尝试从 string<->byte 数组来回切换,除非内容实际上是文本

我必须明确这一点:在 .NET 中,如果byte[]数据不是text,则不要尝试将其转换为 a ,string除了文本通道上二进制数据的特殊Base64编码。这是在 .NET 中工作的人们普遍存在的误解。

于 2009-09-14T15:52:09.377 回答
3

您的问题似乎是您比较字节数组的方式:

Response.Write((fileData == recapturedBytes));

这将始终返回 false,因为您正在比较字节数组的地址,而不是它包含的值。比较字符串数据,或者使用比较字节数组的方法。你也可以这样做:

Response.Write(Convert.ToBase64String(fileData) == Convert.ToBase64String(recapturedBytes));
于 2009-09-14T15:48:38.447 回答