2009-09-14 191 views
19

因此,这里的处理:我试图打开一个文件(从字节),将其转换为一个字符串,所以我可以混淆头中的一些元数据,将其转换回来字节,并保存。我现在遇到的问题是使用此代码。当我将来回转换的字符串(但没有另行修改)与原始字节数组进行比较时,它是不相等的。我该如何做这项工作?将字节数组转换为字符串并返回到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”。

+6

你确定它的UTF-8开头吗? – 2009-09-14 15:34:22

+0

我不确定。我如何判断它是否是? – 2009-09-14 15:46:30

+0

你是什么意思,它是不平等的?你的字符串不相等?你不会得到相同的字符串结果? – Khan 2009-09-14 16:05:00

回答

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

我编辑了这个问题,以显示...代码在评论中没有显示出来! – 2009-09-14 15:45:49

+0

我试过了,他们回来说他们的长度不一样。它一定在别的地方。 – 2009-09-14 16:00:04

+3

查看UTF8编码的文档。可以选择是否指定前导码。如果你发现你生成的字节数组比原来长,那么这可能是你的问题。同样,您需要确保UTF8实际上是正确的编码。至于你怎么知道,你将不得不问谁是谁提供的数据。 – 2009-09-14 16:05:19

3

你的问题就显得你比较字节数组的方式:

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

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

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

由于事实,即.NET字符串使用Unicode字符串,你可以不再做这就像人们在做C.在大多数情况下,你甚至不应该试图来回字符串< - >字节数组,除非内容实际上是文本

我必须清楚这一点:在.NET中,如果byte[]数据不是文本,则不要试图将其转换为一个string除特殊Base64编码在文本二进制数据渠道。这是在.NET中工作的人们广泛存在的误解。

+4

字符串<-> byte []转换通常应通过System.Text.Encoding类之一完成,而不是BitConverter类。 BitConverter.ToString将字节数组转换为数字的十六进制字符串表示形式,它不**将字节数组转换为字符串。 – 2009-09-14 16:07:21

+1

嘿,我知道这不是我的帖子的重点,我应该删除该行。 – 2009-09-14 17:28:10

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

+0

如果有一个字节数组,并且希望用另一个不同长度的序列替换所有出现的特定序列(例如用{0x7E}替换所有出现的{0x7D,0x5E}),那么将使用String来转换为字符串.Replace',然后转换回来是一个合理的方法?上述编码是否将每个字节值0-255替换为其对应的相同编号的编码[编码无损的事实本身并不意味着]? – supercat 2012-10-17 00:33:59

+0

@supercat - 是的方法(提供你使用1252编码)将工作。但是由于我的消息中提到的原因,您仍然无法使用大多数二进制文件格式。 – 2012-10-17 18:48:43

+0

如果使用位置敏感格式,显然必须确保不应该移动的事物不会。即使如此,如果“原始”和“替换”字符串的长度相同,则会出现'String.Replace'似乎有用的情况。 – supercat 2012-10-17 19:25:07

相关问题