【问题标题】:Reading a UTF-8 File in C#在 C# 中读取 UTF-8 文件
【发布时间】:2013-11-15 20:06:04
【问题描述】:

我有这个文件,它使用 UTF-8 编码,我正在尝试读取它。到目前为止,我使用过 BinaryReader、FileStream,我尝试过 File.ReadAllLines。到目前为止,我只得到文件的第一行。

以下是我目前尝试过的一些示例:

public partial class Form1 : Form
    {
        private string filename = @"C:\UNICORN\Server\Fil\Users30.mpm";
        public Form1()
        {
            InitializeComponent();
        }

        private static void clearText(RichTextBox rtb)
        {
            rtb.Text = "";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // use a binary reader
            clearText(richTextBox1);
            StringBuilder sb = new StringBuilder();

            using(BinaryReader br = new BinaryReader(File.Open(filename, FileMode.Open)))
            {
                int pos = 0;
                int length = (int) br.BaseStream.Length;    // length of the file
                byte[] bytes = new byte[length];

                for(int i = 0; i < length; i++)
                {
                    bytes[i] = br.ReadByte();
                }
                sb.Append("File Size: " + bytes.Length + "\n");
                sb.AppendLine(System.Text.ASCIIEncoding.ASCII.GetString(bytes));
            }

            richTextBox1.Text = sb.ToString();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            // use a binary reader
            clearText(richTextBox1);
            StringBuilder sb = new StringBuilder();

            using(BinaryReader br = new BinaryReader(File.Open(filename, FileMode.Open)))
            {
                int pos = 0;
                int length = (int) br.BaseStream.Length;

                sb.Append("File Size: " + length + "\n");
                while (pos < length)
                {
                    var v = br.ReadInt32();
                    sb.Append((char)v + "\n");
                    pos += sizeof (int);
                }

                richTextBox1.Text = sb.ToString();
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            // use a binary reader
            clearText(richTextBox1);
            StringBuilder sb = new StringBuilder();

            using (BinaryReader br = new BinaryReader(File.Open(filename, FileMode.Open)))
            {
                int pos = 0;
                int length = (int)br.BaseStream.Length;    // length of the file
                byte[] bytes = new byte[length];

                sb.Append("File Size: " + bytes.Length + "\n");
                for (int i = 0; i < length; i++)
                {
                    var b = br.ReadByte();
                    sb.Append("Byte: " + b + " - " + (char) b + "\n");
                }

                //sb.AppendLine(System.Text.ASCIIEncoding.ASCII.GetString(bytes));
            }

            richTextBox1.Text = sb.ToString();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            // use a stream reader
            clearText(richTextBox1);
            StringBuilder sb = new StringBuilder();

            using(StreamReader sr = new StreamReader(filename, Encoding.UTF8))
            {
                sb.Append(sr.ReadLine() + "\n");
            }

            richTextBox1.Text = sb.ToString();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            // use a stream reader
            clearText(richTextBox1);
            StringBuilder sb = new StringBuilder();

            using (StreamReader reader = new StreamReader(File.OpenRead(filename)))
            {
                while(!reader.EndOfStream)
                {
                    var line = reader.ReadLine();
                    if(line != null)
                    {
                        sb.AppendLine(line);
                    }
                }
            }

            richTextBox1.Text = sb.ToString();
        }

        private void button6_Click(object sender, EventArgs e)
        {
            // use a file stream and a decoder
            clearText(richTextBox1);
            StringBuilder sb = new StringBuilder();
            byte[] byData = new byte[255];
            char[] charData = new char[255];
            try
            {
                FileStream aFile = new FileStream(filename, FileMode.Open);
                aFile.Seek(55, SeekOrigin.Begin);
                aFile.Read(byData, 0, 100);
            } catch (Exception ex)
            {
                sb.Append("ERROR: " + ex.ToString());
            }

            Decoder d = Encoding.UTF8.GetDecoder();
            d.GetChars(byData, 0, byData.Length, charData, 0);

            foreach(char c in charData)
            {
                sb.Append(c + " ");
            }

            richTextBox1.Text = sb.ToString();
        }

        private void button7_Click(object sender, EventArgs e)
        {
            // find the encoding of a file, just trying to find out the encoding with this
            clearText(richTextBox1);
            StringBuilder sb = new StringBuilder();

            using(var r = new StreamReader(filename, detectEncodingFromByteOrderMarks: true))
            {
                var es = r.CurrentEncoding;
                sb.Append("Encoding: " + es);
            }

            richTextBox1.Text = sb.ToString();
        }

        private void button8_Click(object sender, EventArgs e)
        {
            // use File.ReadAllLines()
            clearText(richTextBox1);
            StringBuilder sb = new StringBuilder();

            foreach(var line in File.ReadAllLines(filename, Encoding.UTF8))
            {
                sb.Append(line.ToString() + "\n");
            }

            richTextBox1.Text = sb.ToString();
        }
    }

所有这些示例只显示文件的一行。您将如何阅读/解析整个文件?

该文件包含一个用户列表,我最终试图读取该文件以找到这些用户名。现在,它只显示文件的第一行“UNICORN 3.06”。

【问题讨论】:

  • 如果是 UTF-8 编码它是一个文本文件,而不是一个二进制文件。另外,如果是 UTF-8,你为什么要使用 System.Text.ASCIIEncoding.ASCII.GetString( 而不是 System.Text.ASCIIEncoding.UTF8.GetString(
  • 当我不知道它是 UTF-8 并且还没有费心将它改回来时,我使用了 ASCII。由于某种原因,我遇到了麻烦。我将该行代码更改为 UTF8,它仍然只读取文件的第一行。
  • 如果这是一个文本文件而不是真正的二进制文件,并且您只想将文件的文本全部作为字符串,我将使用File.ReadAllText
  • 好的,我现在就试试。谢谢。另外,我更改了标题,因为“二进制”现在有点误导。

标签: c# file-io utf-8 binaryreader


【解决方案1】:

如果您只需要文本,ReadAllText 方法会将整个文件读取为 utf-8:

    private void button1_Click(object sender, EventArgs e)
    {
        richTextBox1.Text = File.ReadAllText(filename);
    }

如果您还需要有关文件长度的信息,请将文件读取为字节并将其解码为 utf-8:

    private void button1_Click(object sender, EventArgs e)
    {
        byte[] data = File.ReadAllBytes(filename);
        richTextBox1.Text = "File size: " + data.Length + "\r\n" + Encoding.UTF8.GetString(data);
    }

【讨论】:

  • 谢谢,这确实有效,但是当我尝试使用 File.ReadAllText() 时,它只显示文件的第一行。也许我的文件有问题。文件大小正确,但文本太短。它应该是 1,144kb,但富文本框中只显示了少量文本。
  • @user:那么文件很可能有问题。你确定它是一个文本文件?无论如何,您可以将.bin添加到文件名中,然后在Visual Studio中打开该文件,然后您就可以确切地看到其中的内容了。
  • 谢谢,我不知道。我会尝试在视觉工作室中打开它。我很确定这是一个文本文件。但它确实有一些奇怪的字符。问题是它是某些公司专有的,他们不会告诉我他们是如何解析它的。
  • 我刚刚在visual studio中查看过,我绝对可以看到里面的所有数据。我可能搞砸了我的代码,所以我要再研究一下
【解决方案2】:

我相信 ReadByte 在其构造函数中应该有一个 len 位置 但是:

byte[] fileBytes = File.ReadAllBytes(inputFilename);
StringBuilder sb = new StringBuilder();

foreach(byte b in fileBytes)
{
    sb.Append(Convert.ToString(b, 2).PadLeft(8, '0'));  // adds 8 '0's to left of the string
}

File.WriteAllText(outputFilename, sb.ToString());

【讨论】:

  • 谢谢。我将如何使用它在文件中查找用户名或其他一些信息?
  • 用户名?您只想在 ASCI 文本中查看文件。如果用户甚至以他们的方式存储。否则,您需要知道用户名从哪个字节开始,以及它们是如何编码的。现在你进入逆向工程。那是我非常熟悉的另一种动物>=]
  • 我确实做了一些计算,发现第一行的第一个字符到用户名的第一个字符之间的距离。我还发现文件中每个用户名的第一个字符之间的距离相等。
  • 另外,我想通了。我能够从文件中获得我需要的信息!
  • @user:当您在文件中谈论“距离”时,您是在计算字节数还是字符数? UTF-8 编码文件中的字符可以是一个或多个字节。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多