在C#中将字节数组转换为字符串并再返回

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

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”。

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

编辑

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

 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; } 

当你有原始字节(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}。 鉴于此,您可能会发现将数据保留为字节并一次一个字节地写入替换数据会更容易。

由于.NET字符串使用Unicode字符串这一事实,您不能像C语言中那样执行此操作。在大多数情况下,您甚至不应尝试从字符串< - >字节数组中来回执行,除非内容实际上是文字

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

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

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

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

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