我尝试使用BinaryWriter和Then BinaryReader来做一些代码。 当我想写我使用方法Write()。 但问题是在两行Write方法之间出现一个新的字节,它在十进制31的ASCII表中(某些字符24)。 你可以在这张图片上看到它:
你可以看到索引4(第5个字节)的字节是ASCII十进制值31. 我没有插入。正如您所看到的,前4个字节是为数字(Int32)保留的,其次是其他数据(主要是一些文本 - 现在这并不重要)。
从我写的代码中可以看出: - 进入第1行10号 - 进入第二行文本“这是一些文字......”
为什么会出现第5个字节(12月31日)?
这就是我的代码:
static void Main(string[] args)
{
//
//// SEND - RECEIVE:
//
SendingData();
Console.ReadLine();
}
private static void SendingData()
{
int[] commandNumbers = { 1, 5, 10 }; //10 is for the users (when they send some text)!
for (int i = 0; i < commandNumbers.Length; i++)
{
//convert to byte[]
byte[] allBytes;
using (MemoryStream ms = new MemoryStream())
{
using (BinaryWriter bw = new BinaryWriter(ms))
{
bw.Write(commandNumbers[i]); //allocates 1st 4 bytes - FOR MAIN COMMANDS!
if (commandNumbers[i] == 10)
bw.Write("This is some text at command " + commandNumbers[i]); //HERE ON THIS LINE IS MY QUESTION!!!
}
allBytes = ms.ToArray();
}
//convert back:
int valueA = 0;
StringBuilder sb = new StringBuilder();
foreach (var b in GetData(allBytes).Select((a, b) => new { Value = a, Index = b }))
{
if (b.Index == 0) //1st num
valueA = BitConverter.ToInt32(b.Value, 0);
else //other text
{
foreach (byte _byte in b.Value)
sb.Append(Convert.ToChar(_byte));
}
}
if (sb.ToString().Length == 0)
sb.Append("ONLY COMMAND");
Console.WriteLine("Command = {0} and Text is \"{1}\".", valueA, sb.ToString());
}
}
private static IEnumerable<byte[]> GetData(byte[] data)
{
using (MemoryStream ms = new MemoryStream(data))
{
using (BinaryReader br = new BinaryReader(ms))
{
int j = 0;
byte[] buffer = new byte[4];
for (int i = 0; i < data.Length; i++)
{
buffer[j++] = data[i];
if (i == 3) //SENDING COMMAND DATA
{
yield return buffer;
buffer = new byte[1];
j = 0;
}
else if (i > 3) //SENDING TEXT
{
yield return buffer;
j = 0;
}
}
}
}
}
答案 0 :(得分:4)
如果查看documentation for Write(string)
,您会看到它写了长度前缀字符串。所以31是你的字符串中的字符数 - 完全正常。
答案 1 :(得分:3)
你可能应该使用Encoding.GetBytes然后写字节而不是写字符串
例如
bw.Write(
Encoding.UTF8.GetBytes("This is some text at command " + commandNumbers[i])
);
答案 2 :(得分:2)
当字符串写入二进制流时,它首先要写的是字符串的长度。字符串“这是命令10中的一些文本”有31个字符,这是你看到的值。
答案 3 :(得分:1)
在询问有关它们的问题之前,您应该检查您使用的documentation方法:
以长度为前缀的字符串表示前缀为的字符串长度 字符串是包含其长度的单个字节或单词 串。此方法首先将字符串的长度写为UTF-7 编码无符号整数,然后将多个字符写入 通过使用BinaryWriter实例的当前编码进行流式传输。
- )
(根据维基百科,实际上它是LEB128而不是UTF-7。
答案 4 :(得分:0)
这个字节存在的原因是因为你要添加可变数量的信息,所以需要长度。如果您要添加两个字符串,您在哪里知道第一个结束的位置和第二个结束的位置?
如果你真的不想要或不需要那个长度字节,你总是可以将字符串转换为字节数组并使用它。
答案 5 :(得分:0)
好的,这是我编辑过的代码。我删除了BinaryWriter(当BinaryReader仍在那里!!),现在它工作得很好 - 没有更多的额外字节。
你怎么了?还有什么可以做得更好,让它跑得更快? 特别是我对那个foreach循环感兴趣,它从另一个方法中读取了yield return !! !!新守则:
static void Main(string[] args)
{
//
//// SEND - RECEIVE:
//
SendingData();
Console.ReadLine();
}
private static void SendingData()
{
int[] commands = { 1, 2, 3 };
// 1 - user text
// 2 - new game
// 3 - join game
// ...
for (int i = 0; i < commands.Length; i++)
{
//convert to byte[]
byte[] allBytes;
using (MemoryStream ms = new MemoryStream())
{
// 1.st - write a command:
ms.Write(BitConverter.GetBytes(commands[i]), 0, 4);
// 2nd - write a text:
if (commands[i] == 1)
{
//some example text (like that user sends it):
string myText = "This is some text at command " + commands[i];
byte[] myBytes = Encoding.UTF8.GetBytes(myText);
ms.Write(myBytes, 0, myBytes.Length);
}
allBytes = ms.ToArray();
}
//convert back:
int valueA = 0;
StringBuilder sb = new StringBuilder();
foreach (var b in ReadingData(allBytes).Select((a, b) => new { Value = a, Index = b }))
{
if (b.Index == 0)
{
valueA = BitConverter.ToInt32(b.Value, 0);
}
else
{
sb.Append(Convert.ToChar(b.Value[0]));
}
}
if (sb.ToString().Length == 0)
sb.Append("ONLY COMMAND");
Console.WriteLine("Command = {0} and Text is \"{1}\".", valueA, sb.ToString());
}
}
private static IEnumerable<byte[]> ReadingData(byte[] data)
{
using (MemoryStream ms = new MemoryStream(data))
{
using (BinaryReader br = new BinaryReader(ms))
{
int j = 0;
byte[] buffer = new byte[4];
for (int i = 0; i < data.Length; i++)
{
buffer[j++] = data[i];
if (i == 3) //SENDING COMMAND DATA
{
yield return buffer;
buffer = new byte[1];
j = 0;
}
else if (i > 3) //SENDING TEXT
{
yield return buffer;
j = 0;
}
}
}
}
}