WPF编写的txt阅读器(自适应各种编码,解决显示大数据量txt卡顿的问题)

运行效果如下:
在这里插入图片描述
右击标题栏可选择下一页,上一页,打开文件,关闭程序
注意:
1.因为用textbox一次性显示1M以上的数据会特别慢,所以我在读取完txt文件之后按照每10240Byte字节为一页,每次只让textbox显示一页,这样就可以在打开大数据量txt的时候也能比较快速的显示。
2.即使都是txt文件,其编码方式也会不同,所以可能会导致显示中文为乱码的情况,这就需要在读取文件之前判断文件是什么编码方式,之后再用File.ReadAllText()来读取数据,代码在下方可以看到。
3.
xaml文件主要如下:
<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();
    }
}

}

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GreenHandBruce

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值