运行效果如下:
右击标题栏可选择下一页,上一页,打开文件,关闭程序
注意:
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();
}
}
}