如何将整数字节数组写入以utf8格式编码的文件中

时间:2014-07-23 21:52:57

标签: utf-8

最近我遇到了UTF8的问题。我被要求以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;
        }
    }

当我得到调用WriteInt函数的整数值并尝试将其写入文件时,结果文件的内容总是ANSI,所有字符都是用ANSI格式编写的。 另一方面,如果我只写字符串,则risult文件内容为UTF8,字符串以2字节UFT8格式写入。

出了什么问题。这是实现目标的正确方法。 任何帮助都是值得赞赏的。

乔丝

2 个答案:

答案 0 :(得分:0)

从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);

答案 1 :(得分:0)

由于您将字符串和非字符串数据混合在同一文件中,因此您根本不应在文件的前面编写BOM。您不能将二进制数写入UTF-8编码的文本文件中。您需要将整个文件视为二进制文件,而不是文本,并根据需要对各个字符串进行编码/解码。

您还有一个问题,即知道UTF-8编码字符串的结束位置。我怀疑你试图在它之后写一个null终止符,但你不是那样做的。您可以使用stream.WriteByte(0)

另一方面,从FileStream读取以空字符结尾的字符串很困难。您必须一次一个字节地将流读入缓冲区,直到遇到空值,然后您可以使用UTF8Encoding解码缓冲区。效率不高。

就个人而言,我会将以null结尾的字符串更改为长度为前缀的字符串。然后,您可以使用BinaryWriterBinaryReader为您处理所有事情,例如:

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

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