Utf 8 如何将带有整数的字节数组写入utf8格式编码的文件
最近我遇到了一个UTF8的问题。我被要求写和读一个UTF8编码的文件。乍一看,我觉得这很容易,。。。但事实并非如此。 我的问题是,我必须编写一个包含字符串和整数或短整数的二进制文件。 为此我写了Utf 8 如何将带有整数的字节数组写入utf8格式编码的文件,utf-8,Utf 8,最近我遇到了一个UTF8的问题。我被要求写和读一个UTF8编码的文件。乍一看,我觉得这很容易,。。。但事实并非如此。 我的问题是,我必须编写一个包含字符串和整数或短整数的二进制文件。 为此我写了 byte[] BOM = new byte[] {0xEF, 0xBB, 0xBF}; byte[] Head; byte head4[] = new byte[4]; UTF8Encoding utf8
byte[] BOM = new byte[] {0xEF, 0xBB, 0xBF};
byte[] Head;
byte head4[] = new byte[4];
UTF8Encoding utf8 = new UTF8Encoding(false);
using (FileStream stream = new FileStream(fileName, FileMode.Create))
{
stream.Write( BOM,0, BOM.Length);
Byte[] title = utf8.GetBytes("Hello_Abra");
stream.Write(title, 0, title.Length);
string HeadString = new string('\0', INDEXLength);
Head = utf8.GetBytes(HeadString);
stream.Write( Head, 0, Head.Length);
WriteInt(1258, head4, 0 );
stream.Write( head4, 0, head4.Length);
}
public static void WriteInt(int TheInt, byte[] ToArray, int atIndex)
{
for (int i=0; i<limit; i++)
{
byte thebyte = (byte) (TheInt & 0xff);
ToArray[atIndex+i] = thebyte;
TheInt = TheInt>>8;
}
}
byte[]BOM=新字节[]{0xEF,0xBB,0xBF};
字节[]头;
字节头4[]=新字节[4];
UTF8Encoding utf8=新的UTF8Encoding(假);
使用(FileStream-stream=newfilestream(fileName,FileMode.Create))
{
stream.Write(BOM,0,BOM.Length);
Byte[]title=utf8.GetBytes(“Hello_Abra”);
stream.Write(title,0,title.Length);
字符串头字符串=新字符串('\0',索引长度);
Head=utf8.GetBytes(HeadString);
stream.Write(Head,0,Head.Length);
书面材料(1258,第4类,0);
stream.Write(head4,0,head4.Length);
}
公共静态无效写入(int TheInt,字节[]到数组,int atIndex)
{
对于(int i=0;i>8;
}
}
当我获取调用WriteInt函数的整数值并尝试将其写入文件时,结果文件的内容始终是ANSI,所有字符都是以ANSI格式写入的。
另一方面,如果我只写字符串,risult文件内容是UTF8,字符串以2字节UFT8格式写入
怎么了?这是实现目标的正确方法。
任何帮助都将不胜感激
JOS从int中提取的原始字节不是UTF-8编码的,因此它们会中断解码过程 可以对字符串表示形式进行编码:
Head = utf8.GetBytes("1258".ToString());
stream.Write( Head, 0, Head.Length);
当然,BASE-64会为较大的数字生成较短的字符串:
WriteInt(1258, head4, 0 );
Head = utf8.GetBytes(Convert.ToBase64String(head4));
stream.Write( Head, 0, Head.Length);
由于您在同一个文件中混合了字符串和非字符串数据,因此根本不应该在文件前面写入BOM。您不能将二进制数写入UTF-8编码的文本文件。您需要将整个文件视为二进制,而不是文本,只需根据需要对单个字符串进行编码/解码 您还存在知道UTF-8编码字符串的结束位置的问题。我怀疑您试图在它之后写入空终止符,但您没有这样做。您可以使用
stream.WriteByte(0)
另一方面,从文件流
中读取以null结尾的字符串是很困难的。您必须将流一次读取一个字节到缓冲区中,直到遇到null,然后才能使用UTF8Encoding
对缓冲区进行解码。效率不高
就我个人而言,我会将以null结尾的字符串改为以长度为前缀的字符串。然后您可以使用BinaryWriter
和BinaryReader
为您处理一切,例如:
using (FileStream stream = new FileStream(fileName, FileMode.Create))
{
using (BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8))
{
writer.Write("Hello_Abra");
writer.Write(new string('\0', INDEXLength));
writer.Write(Int32(1258));
}
}
谢谢yoy Remy,我不知道UTF8限制/行为。看来你的建议是正确的…我的意思是..删除BOM并使用混合代码,就像你在示例中所做的那样..但如果我这样做,我怀疑我无法编写固定对元素…我的意思是一块[tex+value][tex+value][tex+value]?这是正确的??当然可以。在二进制文件中,你可以写任何你想写的东西,只要你按照写它们的相同顺序读它们。在我的例子中,文件由
[length+text][length+text][int32]
组成,但你可以改为[type+length+value][type+length+value][type+length+value]
(TLV在许多文件格式和协议中都很常见)。感谢Alireza的回答。我注意到在我的头字节数组中我有错误的UTF8代码,但我尝试了。另一方面,如果我将Base64String转换为UTF8,我如何从二进制文件中读取此字段并将其转换回整数1258??谢谢againI,我真的没想到那么远;-)您可以反向执行此过程。假设您在流中的位置正确,并且由于4字节的int始终转换为8字节的Base-64,这都是ASCII字符,与UTF-8中的一个字节相等:stream.Read(Head,0,8);byte[]b=Convert.FromBase64String(utf8.GetString(Head));int n=0;for(inti=3;i>=0;i--)n=(n
string s;
int i;
using (FileStream stream = new FileStream(fileName, FileMode.Open))
{
using (BinaryReader reader = new BinaryReader(stream, Encoding.UTF8))
{
s = reader.ReadString();
s = reader ReadString();
i = reader.ReadInt32();
}
}