c# 读取大文本文件!!!!!!!!

编程有钱人了 2010-06-05 07:41:52
其实也不大!文件大小才8MB大小!大约50万行数据

先看代码

Thread t;

private void buttonImportResource_Click(object sender, EventArgs e)
{
OpenFileDialog op = new OpenFileDialog();
op.Filter = "文件文件(*.txt)|*.txt";
if (op.ShowDialog() == DialogResult.OK)
{
this.textBoxResource.Text = op.FileName;
dt.Rows.Clear();
t = new Thread(new ParameterizedThreadStart(ReadFile));
t.IsBackground = true;
t.Start(this.textBoxResource.Text);

//ReadFile(this.textBoxResource.Text);
//如果不用线程 把上面3行注释掉 直接用这个方法 并且用
//Application.DoEvents();虽然不会出现假死 但是很慢
//50万要用7分钟。。。

}

}

//响应UI
private void LabelContent(string txt)
{
if (this.labelPercent.InvokeRequired)
this.labelPercent.BeginInvoke(new LabelInvoke(LabelContent), new object[] { txt });
else
this.labelPercent.Text = txt;
}
private void ReadFile(object path)
{
string pps = path as string;
StreamReader sr = new StreamReader(pps, Encoding.GetEncoding("gb2312"));
int line = 0;
while (sr.Peek() > -1)
{
line++;
DataRow dr = dt.NewRow();
dr["序号"] = line.ToString();
dr["资源数据"] = sr.ReadLine();
LabelContent("正在读取第" + line.ToString() + "行");
dt.Rows.Add(dr);
//Application.DoEvents();
}
sr.Close();
resTotal = line;
}



用线程的话 数据小的话 不会出现假死 但是 加载50万 大约 8MB数据时就假死
我加了
if (this.labelPercent.InvokeRequired)
this.labelPercent.BeginInvoke(new LabelInvoke(LabelContent), new object[] { txt });
else
this.labelPercent.Text = txt;

怎么还假死呢???

尤其是读取那该死的50万行数据时
...全文
1456 37 打赏 收藏 转发到动态 举报
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
wziyx513225244 2011-08-31
  • 打赏
  • 举报
回复
标个记号,有用。路过……
七色鸟 2011-08-31
  • 打赏
  • 举报
回复
我是来学习的,
随枫而来 2011-08-27
  • 打赏
  • 举报
回复
学习了!
Char_less 2011-06-23
  • 打赏
  • 举报
回复
都是高手。受教啊。
zebulon1988 2011-05-27
  • 打赏
  • 举报
回复
呵呵,学习了,感谢,呵呵。
timothy888 2011-05-27
  • 打赏
  • 举报
回复
Mark
ritta1988 2010-10-13
  • 打赏
  • 举报
回复
正遇到这种问题 学习中~~
捷哥1999 2010-06-05
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 zhoufoxcn 的回复:]

读一点处理一点,不要全部放到内存中。
如果放你读一个上G的文件,你也全部读到内存中?
学学视频播放软件,读一点显示一点。
[/Quote]

学习 了,思路!
云海玉弓缘 2010-06-05
  • 打赏
  • 举报
回复
推荐给你一个开源的类库 A Fast CSV Reader

To give more down-to-earth numbers, with a 45 MB CSV file containing 145 fields and 50,000 records, the reader was processing about 30 MB/sec. So all in all, it took 1.5 seconds! The machine specs were P4 3.0 GHz, 1024 MB.
kujingzhong 2010-06-05
  • 打赏
  • 举报
回复
或者说建一个线程从后台读也可以
kujingzhong 2010-06-05
  • 打赏
  • 举报
回复
把文件分为若干份,分开读
jsnjlhb 2010-06-05
  • 打赏
  • 举报
回复
高手比较多,我来学习学习,以后肯定会遇到这样的问题
a1875566250 2010-06-05
  • 打赏
  • 举报
回复
不会.NET,不过按照SDK下的开发方式的话,首先CreateFile(获取句柄)——使用一个循环ReadFile,初始分配2048字节缓冲区,每次读2048字节显示,显示后释放资源,继续SetFilePointer设置文件指针向下读,指定全部都读取完毕。
jbz001 2010-06-05
  • 打赏
  • 举报
回复
路过看看
criedshy 2010-06-05
  • 打赏
  • 举报
回复
调用api吧

       [DllImport("kernel32.dll")]
public static extern IntPtr CreateFileMapping(IntPtr hFile,
IntPtr lpFileMappingAttributes, uint flProtect,
uint dwMaximumSizeHigh,
uint dwMaximumSizeLow, string lpName);

[DllImport("kernel32.dll")]
public static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, uint
dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow,
IntPtr dwNumberOfBytesToMap);

[DllImport("kernel32.dll")]
public static extern bool UnmapViewOfFile(IntPtr lpBaseAddress);

[DllImport("kernel32.dll")]
public static extern bool CloseHandle(IntPtr hObject);

[DllImport("kernel32.dll")]
public static extern IntPtr CreateFile(string lpFileName,
int dwDesiredAccess, FileShare dwShareMode, IntPtr securityAttrs,
FileMode dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);

[DllImport("kernel32.dll")]
public static extern uint GetFileSize(IntPtr hFile, IntPtr lpFileSizeHigh);

private string returnback(string path)
{
string str = "";
IntPtr vFileHandle = CreateFile(path,
GENERIC_READ | GENERIC_WRITE, FileShare.Read | FileShare.Write,
IntPtr.Zero, FileMode.Open,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, IntPtr.Zero);
if (INVALID_HANDLE_VALUE != (int)vFileHandle)
{
IntPtr vMappingHandle = CreateFileMapping(
vFileHandle, IntPtr.Zero, PAGE_READWRITE, 0, 0, "~MappingTemp");
if (vMappingHandle != IntPtr.Zero)
{
IntPtr vHead = MapViewOfFile(vMappingHandle,
FILE_MAP_COPY | FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, IntPtr.Zero);
if (vHead != IntPtr.Zero)
{
uint vSize = GetFileSize(vFileHandle, IntPtr.Zero);
byte[] temp = new byte[vSize];
for (int i = 0; i < vSize; i++)
{
byte vTemp = Marshal.ReadByte((IntPtr)((int)vHead + i));
temp[i] = vTemp;
}
ASCIIEncoding encoding = new ASCIIEncoding();
str = encoding.GetString(temp).Replace("\r\n", ",");
UnmapViewOfFile(vHead);
}
CloseHandle(vMappingHandle);
CloseHandle(vHead);
}
CloseHandle(vFileHandle);

}
return str;
}



doubleu2005 2010-06-05
  • 打赏
  • 举报
回复
学习了
马老虎 2010-06-05
  • 打赏
  • 举报
回复
解决假死 就用BackgroundWorker吧。

兔子-顾问 2010-06-05
  • 打赏
  • 举报
回复
你界面更新比较多,每20行更新界面一次试试?
编程有钱人了 2010-06-05
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 wuyazhe 的回复:]

楼主的编码风格还停留在vs2003的时代,建议你学习一下lambda,匿名方法,代码能简化很多,帮你修改一下,就清爽了。效率没仔细看,但觉得不会有你说的那么慢。
C# code


private void buttonImportResource_Click(object sender, EventArgs e)
{
OpenFileDialog op = new OpenFile……
[/Quote]

谢谢你 读取20万条 花了1分钟
能再快点吗?有的人说 读 100MB 就十几秒。。。
多线程???
八爪鱼-杭州 2010-06-05
  • 打赏
  • 举报
回复
虽然你开了另外一个线程读取数据,便是调用LabelContent频繁了,每读一行就调用一次,50万条要刷50万次加界面,肯定会有假死现象。建议你把读取进度模糊化,使用进度条来表示,每隔n条才刷新一次界面,用户体验就会提升不少。你可以试试BackGroundWorker,非常适合你这种情况。
加载更多回复(16)

110,544

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧