代码之家  ›  专栏  ›  技术社区  ›  Brian Hicks

将字节数组转换为字符串,然后在C中重新转换#

  •  19
  • Brian Hicks  · 技术社区  · 15 年前

    所以,我要做的是:我试图打开一个文件(从字节开始),将它转换成一个字符串,这样我就可以处理头中的一些元数据,将它转换回字节,然后保存它。我现在遇到的问题是这个代码。当我将来回转换的字符串(但不进行其他修改)与原始字节数组进行比较时,它是不相等的。我怎样才能做到这一点?

    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.utf8编码”。

    4 回复  |  直到 9 年前
        1
  •  16
  •   Adam Robinson    15 年前

    在上尝试静态函数 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;
    }
    
        2
  •  7
  •   Peter Mortensen John Conde    9 年前

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

    Encoding.GetEncoding(1252)
    

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

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

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

    你想把ABC改成DEF,这应该可以按你的意愿工作。但是,如果你想把abc改为wxyz,你必须重写“c”后面的字节,否则你(本质上)会把所有的东西都移到右边一个字节。在典型的二进制文件中,这会把事情搞得一团糟。

    如果“abc”后面的字节是空格或空字符,那么编写更大的替换数据可能不会造成麻烦——但您仍然不能在.NET字符串中用wxyz替换abc,使其更长——您必须用wxyz替换abc后面的任何内容。考虑到这一点,您可能会发现,只需将数据保留为字节,然后一次只写一个字节就可以了。

        3
  •  5
  •   Peter Mortensen John Conde    9 年前

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

    我必须澄清这一点: 在.NET中,如果 byte[] 数据不是 文本 ,则不要尝试将其转换为 string 除了特别的 Base64 通过文本通道对二进制数据进行编码。这是在.NET中工作的人们普遍持有的误解。

        4
  •  3
  •   Peter Mortensen John Conde    9 年前

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

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

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

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