为什么byte []不按预期进行字符串和返回工作

mcm*_*lab 7 c# byte

我有这个代码:

Int32 i1 = 14000000;
byte[] b = BitConverter.GetBytes(i1);
string s = System.Text.Encoding.UTF8.GetString(b);
byte[] b2 = System.Text.Encoding.UTF8.GetBytes(s);
Int32 i2 = BitConverter.ToInt32(b2,0);;
Run Code Online (Sandbox Code Playgroud)

i2等于-272777233.为什么不是输入值?(14000000)?

编辑:我想要做的是将它附加到另一个字符串,然后我使用WriteAllText写入文件

Jon*_*eet 10

您不应该使用Encoding.GetString任意二进制数据转换为字符串.该方法仅适用于使用特定编码编码为二进制数据的文本.

相反,您希望使用能够可逆地表示任意二进制数据的文本表示.最常见的两种方法是base64和hex.Base64是.NET中最简单的:

string base64 = Convert.ToBase64String(originalBytes);
...
byte[] recoveredBytes = Convert.FromBase64String(base64);
Run Code Online (Sandbox Code Playgroud)

对此有一些警告:

  • 如果要将此字符串用作URL参数,则应使用web64安全版本的base64; 我不知道在.NET中直接支持它,但你可以很容易地找到解决方案
  • 你只能这样做在所有如果你真的需要字符串格式的数据.如果您只是想将其写入文件或类似文件,最简单的方法是将其保存为二进制数据
  • Base64不是很易读; 如果您希望人类能够以文本形式读取数据而无需额外的工具,请使用十六进制.(有关将二进制数据转换为十六进制和后退的具体问题.)


Alv*_*ong 9

因为Encoding班级不会只是为了任何事情而工作.如果"字符"(在UTF-8的情况下可能是几个字节)不是该特定字符集中的有效字符(在您的情况下为UTF-8),则它将使用替换字符.

一个问号(U + 003F)

(来源:http://msdn.microsoft.com/en-us/library/ms404377.aspx#FallbackStrategy)

有些情况下它只是一个?,例如在ASCII/CP437/ISO 8859-1中,但有一种方法可供您选择如何处理它.(见上面的链接)

例如,如果您尝试转换(byte)128为ASCII:

string s = System.Text.Encoding.ASCII.GetString(new byte[] { 48, 128 }); // s = "0?"
Run Code Online (Sandbox Code Playgroud)

然后将其转换回来:

byte[] b = System.Text.Encoding.ASCII.GetBytes(s); // b = new byte[] { 48, 63 }
Run Code Online (Sandbox Code Playgroud)

不会得到原始的字节数组.

这可以作为参考:检查编码中是否存在字符


我无法想象为什么你需要将字节数组转换为字符串.这显然没有任何意义.假设你要写一个流,你可以直接写byte[].如果你需要在某些文本表示中使用它,那么将它转换为字符串yourIntegerVar.ToString()并使用int.TryParse它来取回它是完全合理的.


编辑:

可以写一个字节数组到一个文件,但你不打算"串联"的字节数组为字符串,并使用偷懒的方法File.WriteAllText,因为它要处理的编码转换,你可能最终将不得不问号?各地你的档案.相反,打开a FileStream并使用FileStream.Write直接写入字节数组.或者,您可以使用a BinaryWriter以二进制形式(也是字符串)直接写入整数,并使用其对应方BinaryReader读取它.

例:

FileStream fs;

fs = File.OpenWrite(@"C:\blah.dat");
BinaryWriter bw = new BinaryWriter(fs, Encoding.UTF8);
bw.Write((int)12345678);
bw.Write("This is a string in UTF-8 :)"); // Note that the binaryWriter also prefix the string with its length...
bw.Close();

fs = File.OpenRead(@"C:\blah.dat");
BinaryReader br = new BinaryReader(fs, Encoding.UTF8);
int myInt = br.ReadInt32();
string blah = br.ReadString(); // ...so that it can read it back.
br.Close();
Run Code Online (Sandbox Code Playgroud)

此示例代码将生成一个与以下hexdump匹配的文件:

00  4e 61 bc 00 1c 54 68 69 73 20 69 73 20 61 20 73  Na¼..This is a s  
10  74 72 69 6e 67 20 69 6e 20 55 54 46 2d 38 20 3a  tring in UTF-8 :  
20  29                                               )   
Run Code Online (Sandbox Code Playgroud)

请注意,BinaryWriter.Write(string)字符串前缀也是其长度,在读回时依赖于它,因此使用文本编辑器编辑生成的文件是不合适的.(你正在用二进制形式写一个整数,所以我希望这是可以接受的吗?)


Guf*_*ffa 5

它不起作用,因为您正在反向使用编码。

编码用于将文本转为字节,然后再转回文本。您不能将任意字节转换为文本。每个字符都有一个相应的字节模式,但每个字节模式都不会转换为一个字符。

如果您想以紧凑的方式将字节表示为文本,请使用 base-64 编码:

Int32 i1 = 14000000;
byte[] b = BitConverter.GetBytes(i1);
string s = Convert.ToBase64String(b);

byte[] b2 = Convert.FromBase64String(s);
Int32 i2 = BitConverter.ToInt32(b2, 0);
Run Code Online (Sandbox Code Playgroud)