Txt reader written by WPF (adapt to various encodings, solve the problem of txt lagging when displaying large amounts of data)

The running effect is as follows:
Insert picture description here
right-click the title bar to select the next page, the previous page, open the file, and close the program.
Note:
1. Because it will be very slow to display more than 1M data in textbox at a time, so I read the txt file after According to every 10240Byte bytes as a page, only let the textbox display one page at a time, so that it can be displayed more quickly when the large amount of data is opened.
2. Even if they are all txt files, their encoding methods will be different, so it may cause the display of Chinese to be garbled. This requires judging the encoding method of the file before reading the file, and then use File.ReadAllText() to do Read the data, the code can be seen below.
3. The
main xaml files are as follows:
<Window.Resources>




    </ContextMenu>
</Window.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="20"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Label Name="titalLabel" Grid.Row="0" Background="Gray" MouseMove="titalLabel_MouseMove" ContextMenu="{StaticResource contextMenu}"></Label>
    <ScrollViewer Name="scrollView" Margin="0,0,0.4,0" Grid.RowSpan="2" Grid.Row="1" ScrollChanged="ScrollViewer_ScrollChanged">
    <TextBox Name="textBox" TextWrapping="Wrap"></TextBox>
    </ScrollViewer>
</Grid>

MainWindow.cs文件代码如下:
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Reader
{
///
/// MainWindow.xaml 的交互逻辑
///
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
SolidColorBrush NewColor = new SolidColorBrush();
NewColor.Color = Color.FromArgb(255,230,231,232);
textBox.Background = NewColor;
SolidColorBrush NewColor2 = new SolidColorBrush();
NewColor2.Color = Color.FromArgb(255, 207, 214, 229);
titalLabel.Background = NewColor2;
}

    private void titalLabel_MouseMove(object sender, MouseEventArgs e)
    {
        if(e.LeftButton == MouseButtonState.Pressed)
        {
            this.DragMove();
        }
    }

    private void Window_KeyDown(object sender, KeyEventArgs e)
    {
        if(e.Key == Key.Escape)
        {
            this.Close();
        }
    }
    private List<string> mTextList = new List<string>();
    private int nCrtNum = 0;
    private void OpenFile_Click(object sender, RoutedEventArgs e)
    {
        mTextList.Clear();
        OpenFileDialog openFileDialog1 = new OpenFileDialog();
        openFileDialog1.Filter = "文本文件(*.txt)|*.txt|(*.rtf)|*.rtf";
        if (openFileDialog1.ShowDialog() == true)
        {
            FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
            Encoding encoding = GetType(fs);
            string str = File.ReadAllText(openFileDialog1.FileName, encoding);              
            int nNum = str.Length / 10240;
            if (str.Length % 10240 != 0)
            {
                nNum++;
            }
            for (int i = 0;i<nNum;i++)
            {
                if(i == nNum-1)
                {
                    int nlen = str.Length - i * 10240;
                    mTextList.Add(str.Substring(i * 10240, nlen));
                }
                else
                {
                    mTextList.Add(str.Substring(i * 10240, 10240));
                }                    
            }
            textBox.Text = mTextList.ElementAt(0);
        }
    }
    //public System.Text.Encoding GetFileEncodeType(string filename)
    //{
    //    System.IO.FileStream fs = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read);
    //    System.IO.BinaryReader br = new System.IO.BinaryReader(fs);
    //    Byte[] buffer = br.ReadBytes(2);
    //    if (buffer[0] >= 0xEF)
    //    {
    //        if (buffer[0] == 0xEF && buffer[1] == 0xBB)
    //        {
    //            return System.Text.Encoding.UTF8;
    //        }
    //        else if (buffer[0] == 0xFE && buffer[1] == 0xFF)
    //        {
    //            return System.Text.Encoding.BigEndianUnicode;
    //        }
    //        else if (buffer[0] == 0xFF && buffer[1] == 0xFE)
    //        {
    //            return System.Text.Encoding.Unicode;
    //        }
    //        else
    //        {
    //            return System.Text.Encoding.Default;
    //        }
    //    }
    //    else
    //    {
    //        return System.Text.Encoding.Default;
    //    }
    //}
    /// <summary>
    /// 通过给定的文件流,判断文件的编码类型
    /// </summary>
    /// <param name=“fs“>文件流</param>
    /// <returns>文件的编码类型</returns>
    public static System.Text.Encoding GetType(FileStream fs)
    {
        byte[] Unicode = new byte[] { 0xFF, 0xFE, 0x41 };
        byte[] UnicodeBIG = new byte[] { 0xFE, 0xFF, 0x00 };
        byte[] UTF8 = new byte[] { 0xEF, 0xBB, 0xBF }; //带BOM
        Encoding reVal = Encoding.Default;

        BinaryReader r = new BinaryReader(fs, System.Text.Encoding.Default);
        int i;
        int.TryParse(fs.Length.ToString(), out i);
        byte[] ss = r.ReadBytes(i);
        if (IsUTF8Bytes(ss) || (ss[0] == 0xEF && ss[1] == 0xBB && ss[2] == 0xBF))
        {
            reVal = Encoding.UTF8;
        }
        else if (ss[0] == 0xFE && ss[1] == 0xFF && ss[2] == 0x00)
        {
            reVal = Encoding.BigEndianUnicode;
        }
        else if (ss[0] == 0xFF && ss[1] == 0xFE && ss[2] == 0x41)
        {
            reVal = Encoding.Unicode;
        }
        r.Close();
        return reVal;

    }

    /// <summary>
    /// 判断是否是不带 BOM 的 UTF8 格式
    /// </summary>
    /// <param name=“data“></param>
    /// <returns></returns>
    private static bool IsUTF8Bytes(byte[] data)
    {
        int charByteCounter = 1; //计算当前正分析的字符应还有的字节数
        byte curByte; //当前分析的字节.
        for (int i = 0; i < data.Length; i++)
        {
            curByte = data[i];
            if (charByteCounter == 1)
            {
                if (curByte >= 0x80)
                {
                    //判断当前
                    while (((curByte <<= 1) & 0x80) != 0)
                    {
                        charByteCounter++;
                    }
                    //标记位首位若为非0 则至少以2个1开始 如:110XXXXX...........1111110X
                    if (charByteCounter == 1 || charByteCounter > 6)
                    {
                        return false;
                    }
                }
            }
            else
            {
                //若是UTF-8 此时第一位必须为1
                if ((curByte & 0xC0) != 0x80)
                {
                    return false;
                }
                charByteCounter--;
            }
        }
        if (charByteCounter > 1)
        {
            throw new Exception("非预期的byte格式");
        }
        return true;
    }
    private void CloseWnd_Click(object sender, RoutedEventArgs e)
    {
        this.Close();
    }

    private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        //if (e.VerticalOffset + e.ViewportHeight == e.ExtentHeight && e.ViewportHeight != 0)//到底了
        //{
        //    nCrtNum++;
        //    if (nCrtNum > (mTextList.Count() - 1))
        //        return;
        //    textBox.Text = mTextList.ElementAt(nCrtNum);
        //    scrollView.ScrollToTop();
        //}
    }

    private void NextPage_Click(object sender, RoutedEventArgs e)
    {
        nCrtNum++;
        if (nCrtNum > (mTextList.Count() - 1))
        {
            nCrtNum--;
            return;
        }                
        textBox.Text = mTextList.ElementAt(nCrtNum);
        scrollView.ScrollToTop();
    }

    private void PreviewPage_Click(object sender, RoutedEventArgs e)
    {
        nCrtNum--;
        if (nCrtNum<0)
        {
            nCrtNum++;
            return;
        }
        textBox.Text = mTextList.ElementAt(nCrtNum);
        scrollView.ScrollToBottom();
    }
}

}

Guess you like

Origin blog.csdn.net/weixin_43935474/article/details/105179076
Recommended