C# 如何根据换行分割超大TXT文件(3.2G) 每行长度一样?那就计算分割文件SIZE,直接二进制操作就快了 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 FileStream fsIn = new FileStream(fileIn, FileMode.Open, FileAccess.Read); FileStream fsOut = new FileStream(fileOut, FileMode.OpenOrCreate, FileAccess.Write); int bufferLen = 4096*1000; byte[] buffer = new byte[bufferLen]; int bytesRead; bytesRead = fsIn.Read(buffer, 0, bufferLen); fsOut.Write(buffer, 0, bytesRead); protected void Button1_Click(object sender, EventArgs e) { int iFileSize = 10000 * 1024; FileStream TempStream = null; BinaryWriter TempWriter=null; //根据选择来设定分割的小文件的大小 string filepath = @"Z:\ftpfoot\ksd_rtx\KSD_RTX_140131.txt"; //反之则在计算机创建目录 FileStream SplitFileStream = new FileStream(filepath, FileMode.Open); //以文件的全路对应的字符串和文件打开模式来初始化FileStream文件流实例 BinaryReader SplitFileReader = new BinaryReader(SplitFileStream); //以FileStream文件流来初始化BinaryReader文件阅读器 byte[] TempBytes; //每次分割读取的最大数据 int iFileCount = (int)(SplitFileStream.Length / iFileSize); //小文件总数 //progressBar1.Maximum = iFileCount; if (SplitFileStream.Length % iFileSize != 0) iFileCount++; string[] TempExtra = filepath.Split('.'); /* 循环将大文件分割成多个小文件 */ for (int i = 1; i <= iFileCount; i++) { string sTempFileName = @"Z:\ftpfoot\ksd_rtx\" + i.ToString().PadLeft(4, '0') + "." + TempExtra[TempExtra.Length - 1]; //小文件名 //确定小文件的文件名称 TempStream = new FileStream(sTempFileName, FileMode.OpenOrCreate); //根据文件名称和文件打开模式来初始化FileStream文件流实例 TempWriter = new BinaryWriter(TempStream); //以FileStream实例来创建、初始化BinaryWriter书写器实例 TempBytes = SplitFileReader.ReadBytes(iFileSize); //从大文件中读取指定大小数据 TempWriter.Write(TempBytes); //把此数据写入小文件 TempWriter.Close(); //progressBar1.Value = 0; //String fileName = @"Z:\ftpfoot\ksd_rtx\KSD_RTX_140131.txt"; //FilePartition objFp = new FilePartition(fileName); //if (objFp.OnPartitionFile()) // Response.Write(String.Format("共切割成{0}个文件.", objFp.FileCount)); } if (SplitFileReader != null) SplitFileReader.Close(); if (TempWriter != null) TempWriter.Close(); if (TempStream != null) TempStream.Close(); } 这个给力.net对于大文件 我一直无解来学习下 我以前写过一个按行读取分割的,分割几百MB的文档没问题,你的几GB不知道行不行. 代码发给我看看呗,[email protected],数据量太大,真麻烦 string name = Path.GetFileNameWithoutExtension(openFileDialog.FileName); saveFileDialog.Filter = "文本文件(*.txt)|*.txt"; int line = 0,num=0; if (!Directory.Exists(dizhi.Text + "\\" + name)) { Directory.CreateDirectory(dizhi.Text + "\\" + name); } string hang; StreamReader sr = new StreamReader(mubiao.Text, System.Text.Encoding.GetEncoding("UTF-8")); while ((hang = sr.ReadLine()) != null) { line++; StreamWriter sw = new StreamWriter(dizhi.Text + "\\" + name + "\\A" + num + ".txt", true, System.Text.Encoding.GetEncoding("UTF-8")); sw.WriteLine(hang); sw.Close(); if (line == 2000) { line = 0; num++; } } 没有程序,说说我的思路:使用BinaryReader : 首先:假设截取的文件大小为1M(1024*1024 字节),从头读取。binaryReader.BaseStream.Position = 1024*1024-1;读取 1024*1024-1 处的字节判断是不是 换行符,不是的话,读取1024*1024 处,知道为换行符为止(假设为止为B)则,读取0-BbinaryReader.ReadBytes(B-0+1)个字节并保存。然后从B+1 处读取,知道结束。 /// <summary> /// 分割大文件成独立小文件并保存小文件至指定目录 /// </summary> /// <param name="splitunit">分割单位(KB,MB)</param> /// <param name="intFlag">分割大小</param> /// <param name="destCatalog">保存路径</param> /// <param name="sourcefileurl">源文件路径</param> /// <returns>true表示分割成功,false表示分割失败</returns> public static bool SplitFile(string splitunit, int intFlag, string destCatalog, string sourcefileurl) { bool suc = false; try { int iFileSize = 0; switch (splitunit) { case "Byte": iFileSize = intFlag; break; case "KB": iFileSize = 1024 * intFlag; break; case "MB": iFileSize = 1024 * 1024 * intFlag; break; default: iFileSize = 1024 * 1024 * 1024 * intFlag; break; } FileStream SplitFileStream = new FileStream(sourcefileurl, FileMode.Open); BinaryReader SplitFileReader = new BinaryReader(SplitFileStream); Byte[] TempBytes; int ifilecount = (int)(SplitFileStream.Length / iFileSize); if (SplitFileStream.Length % iFileSize != 0) { ifilecount++; } for (int i = 1; i <= ifilecount; i++) { string sTempFileName = destCatalog + "\\" + i.ToString().PadLeft(4, '0') + Path.GetExtension(destCatalog); FileStream TempStream = new FileStream(sTempFileName, FileMode.OpenOrCreate); BinaryWriter bw = new BinaryWriter(TempStream); TempBytes = SplitFileReader.ReadBytes(iFileSize); bw.Write(TempBytes); bw.Close(); TempStream.Close(); } SplitFileStream.Close(); SplitFileReader.Close(); suc = true; } catch { suc = false; } return suc; } 这个思路我感觉可以,但是根据字节怎么得到文本里的内容呢这容易 先用FileStream读取文件长度 然后设定每个文件长度大小为多少假如每个文件为1M左右那就是 文件个数 =FileLength/1024/1024;接下来利用上面的Position 直接定位 第一个文件就是0 到 (1*1024 *1024)字节先读取这个0- (1*1024 *1024)字节,然后判断(1*1024 *1024)处的两个字节是不是\r\n代码可以这样 write(0,Position);把大块先写到文件里while(true){ byte[] buff=new byte[1];这里从Position后每次读1个字节 stream.Read(buff,0,1); write(buff)把读取到的写到文件中 if(buff[0]='\n') { break; } }然后直接利用Position即可直接向下读下面做第二个文件的处理这是先分块的另外一种是直接FileStream streamlong MaxLengthFileStream newFile=new 第一个文件while(true){ 每次读取两个字节 写入文件块 if(这两个字节是否为\r\n && 是否超出MaxLength) { newFile =new (新文件); } } 这个思路我感觉可以,但是根据字节怎么得到文本里的内容呢这容易 先用FileStream读取文件长度 然后设定每个文件长度大小为多少假如每个文件为1M左右那就是 文件个数 =FileLength/1024/1024;接下来利用上面的Position 直接定位 第一个文件就是0 到 (1*1024 *1024)字节先读取这个0- (1*1024 *1024)字节,然后判断(1*1024 *1024)处的两个字节是不是\r\n代码可以这样 write(0,Position);把大块先写到文件里while(true){ byte[] buff=new byte[1];这里从Position后每次读1个字节 stream.Read(buff,0,1); write(buff)把读取到的写到文件中 if(buff[0]='\n') { break; } }然后直接利用Position即可直接向下读下面做第二个文件的处理这是先分块的另外一种是直接FileStream streamlong MaxLengthFileStream newFile=new 第一个文件while(true){ 每次读取两个字节 写入文件块 if(这两个字节是否为\r\n && 是否超出MaxLength) { newFile =new (新文件); } }这个思路我感觉可以,但是根据字节怎么得到文本里的内容呢这容易 先用FileStream读取文件长度 然后设定每个文件长度大小为多少假如每个文件为1M左右那就是 文件个数 =FileLength/1024/1024;接下来利用上面的Position 直接定位 第一个文件就是0 到 (1*1024 *1024)字节先读取这个0- (1*1024 *1024)字节,然后判断(1*1024 *1024)处的两个字节是不是\r\n代码可以这样 write(0,Position);把大块先写到文件里while(true){ byte[] buff=new byte[1];这里从Position后每次读1个字节 stream.Read(buff,0,1); write(buff)把读取到的写到文件中 if(buff[0]='\n') { break; } }然后直接利用Position即可直接向下读下面做第二个文件的处理这是先分块的另外一种是直接FileStream streamlong MaxLengthFileStream newFile=new 第一个文件while(true){ 每次读取两个字节 写入文件块 if(这两个字节是否为\r\n && 是否超出MaxLength) { newFile =new (新文件); } }不太明白 就这个你用FileStream 的类fs.Read();fs.ReadByte();基本是不会占内存的方法读取 他是直接定位到文件某处读取几个字节,不像其他的类ReadLine()这样是先加载整个文件然后再读取所以造成你的程序无法加载大文件,用FileStream几个字节几个字节读是不会有问题 的所以我上面说的你读两个字节就可以了, 我根据你第一个方法读取我的byte字节数组,读不到换行符,也读不到内容,只是一下字节数字 这个思路我感觉可以,但是根据字节怎么得到文本里的内容呢换行符转换成字节byte1 如果等于binaryReader.ReadByte()获得字节,说明就是换行符,就可读取一段数据了 这个思路我感觉可以,但是根据字节怎么得到文本里的内容呢换行符转换成字节byte1 如果等于binaryReader.ReadByte()获得字节,说明就是换行符,就可读取一段数据了或者将你获得的字节转化成字符串和换行符比较 /// <summary> /// 分割文件 /// </summary> /// <param name="fileName">原文件路径</param> /// <param name="outputFileName">目标文件路径</param> /// <param name="childFileLong">子文件大小(M)</param> private void SplitText(string fileName,string outputFileName, long childFileLong) { FileStream fileStream = new FileStream(fileName, FileMode.Open); BinaryReader binaryReader = new BinaryReader(fileStream); long childFilecount = 1024 * 1024; long allCount = fileStream.Length; int outputFileNumber = 0; long startPositon = 0; binaryReader.BaseStream.Position =startPositon+ childFilecount - 1; while (binaryReader.BaseStream.Position <= allCount) { while (Encoding.Default.GetString(new byte[] { binaryReader.ReadByte() }) != "/n" && binaryReader.BaseStream.Position<allCount-1) { binaryReader.BaseStream.Position++; } FileStream fileStreamOut = new FileStream(outputFileName+outputFileNumber.ToString(), FileMode.CreateNew); using (BinaryWriter binaryWriter = new BinaryWriter(fileStreamOut)) { binaryWriter.Write(binaryReader.ReadBytes((int)(binaryReader.BaseStream.Position - startPositon + 1))); } startPositon = binaryReader.BaseStream.Position + 1; binaryReader.BaseStream.Position = startPositon + childFilecount - 1; outputFileNumber++; } binaryReader.Close(); } 以上代码供你参考,没有测试。如果子文件也比较大,为了避免占用大量内存空间, binaryWriter.Write(binaryReader.ReadBytes((int)(binaryReader.BaseStream.Position - startPositon + 1)));这部分需要再进行处理,分割成更小的片段读取写入。 直接用FileStream一边读取一边写入,遇到换行符的时候新建文件! while (binaryReader.BaseStream.Position <= allCount) { while (Encoding.Default.GetString(new byte[] { binaryReader.ReadByte() }) != "/n" && binaryReader.BaseStream.Position<allCount-1) { binaryReader.BaseStream.Position++; }这两个循环次数太多了,我得到的文件allCount 长度是13亿多,但是binaryReader.BaseStream.Position的position值只有100多万这样也很慢 c#中2个DataSet合并的问题 TabControl 控件 布局问题(应该很简单的问题,在线等) 心情好乱啊。老婆跟我分手了 C#中的Semaphone可以用在进程之间么? 傳多個不同的參數到sql中 新手学习C#请教几个问题 请问各位有用过shimgvw.dll这个DLL吗? remoting的问题!! C# webbrowser 如何屏蔽脚本 如何控制文字输出到页面的格式~小弟把最后的分搭上了,还望能得到一个满意的答复! 如何让datagridview全选的时候,不包含行标列? CMD执行命令的问题.
FileStream fsIn = new FileStream(fileIn, FileMode.Open, FileAccess.Read);
FileStream fsOut = new FileStream(fileOut, FileMode.OpenOrCreate, FileAccess.Write); int bufferLen = 4096*1000;
byte[] buffer = new byte[bufferLen];
int bytesRead;
bytesRead = fsIn.Read(buffer, 0, bufferLen);
fsOut.Write(buffer, 0, bytesRead);
protected void Button1_Click(object sender, EventArgs e)
{
int iFileSize = 10000 * 1024;
FileStream TempStream = null;
BinaryWriter TempWriter=null;
//根据选择来设定分割的小文件的大小
string filepath = @"Z:\ftpfoot\ksd_rtx\KSD_RTX_140131.txt";
//反之则在计算机创建目录
FileStream SplitFileStream = new FileStream(filepath, FileMode.Open);
//以文件的全路对应的字符串和文件打开模式来初始化FileStream文件流实例
BinaryReader SplitFileReader = new BinaryReader(SplitFileStream);
//以FileStream文件流来初始化BinaryReader文件阅读器
byte[] TempBytes;
//每次分割读取的最大数据
int iFileCount = (int)(SplitFileStream.Length / iFileSize);
//小文件总数
//progressBar1.Maximum = iFileCount;
if (SplitFileStream.Length % iFileSize != 0) iFileCount++;
string[] TempExtra = filepath.Split('.');
/* 循环将大文件分割成多个小文件 */
for (int i = 1; i <= iFileCount; i++)
{
string sTempFileName = @"Z:\ftpfoot\ksd_rtx\" + i.ToString().PadLeft(4, '0') + "." + TempExtra[TempExtra.Length - 1]; //小文件名
//确定小文件的文件名称
TempStream = new FileStream(sTempFileName, FileMode.OpenOrCreate);
//根据文件名称和文件打开模式来初始化FileStream文件流实例
TempWriter = new BinaryWriter(TempStream);
//以FileStream实例来创建、初始化BinaryWriter书写器实例
TempBytes = SplitFileReader.ReadBytes(iFileSize);
//从大文件中读取指定大小数据
TempWriter.Write(TempBytes);
//把此数据写入小文件
TempWriter.Close();
//progressBar1.Value = 0;
//String fileName = @"Z:\ftpfoot\ksd_rtx\KSD_RTX_140131.txt";
//FilePartition objFp = new FilePartition(fileName);
//if (objFp.OnPartitionFile())
// Response.Write(String.Format("共切割成{0}个文件.", objFp.FileCount));
}
if (SplitFileReader != null) SplitFileReader.Close();
if (TempWriter != null) TempWriter.Close();
if (TempStream != null) TempStream.Close();
}
来学习下
代码发给我看看呗,[email protected],数据量太大,真麻烦
saveFileDialog.Filter = "文本文件(*.txt)|*.txt";
int line = 0,num=0;
if (!Directory.Exists(dizhi.Text + "\\" + name))
{
Directory.CreateDirectory(dizhi.Text + "\\" + name);
}
string hang;
StreamReader sr = new StreamReader(mubiao.Text, System.Text.Encoding.GetEncoding("UTF-8"));
while ((hang = sr.ReadLine()) != null)
{
line++;
StreamWriter sw = new StreamWriter(dizhi.Text + "\\" + name + "\\A" + num + ".txt", true, System.Text.Encoding.GetEncoding("UTF-8"));
sw.WriteLine(hang);
sw.Close();
if (line == 2000)
{
line = 0;
num++;
}
}
使用BinaryReader :
首先:假设截取的文件大小为1M(1024*1024 字节),从头读取。
binaryReader.BaseStream.Position = 1024*1024-1;
读取 1024*1024-1 处的字节判断是不是 换行符,不是的话,读取1024*1024 处,知道为换行符为止(假设为止为B)
则,读取0-B
binaryReader.ReadBytes(B-0+1)个字节并保存。
然后从B+1 处读取,知道结束。
/// 分割大文件成独立小文件并保存小文件至指定目录
/// </summary>
/// <param name="splitunit">分割单位(KB,MB)</param>
/// <param name="intFlag">分割大小</param>
/// <param name="destCatalog">保存路径</param>
/// <param name="sourcefileurl">源文件路径</param>
/// <returns>true表示分割成功,false表示分割失败</returns>
public static bool SplitFile(string splitunit, int intFlag, string destCatalog, string sourcefileurl)
{
bool suc = false;
try
{
int iFileSize = 0;
switch (splitunit)
{
case "Byte":
iFileSize = intFlag;
break;
case "KB":
iFileSize = 1024 * intFlag;
break;
case "MB":
iFileSize = 1024 * 1024 * intFlag;
break;
default:
iFileSize = 1024 * 1024 * 1024 * intFlag;
break;
}
FileStream SplitFileStream = new FileStream(sourcefileurl, FileMode.Open);
BinaryReader SplitFileReader = new BinaryReader(SplitFileStream);
Byte[] TempBytes;
int ifilecount = (int)(SplitFileStream.Length / iFileSize);
if (SplitFileStream.Length % iFileSize != 0)
{
ifilecount++;
}
for (int i = 1; i <= ifilecount; i++)
{
string sTempFileName = destCatalog + "\\" + i.ToString().PadLeft(4, '0') + Path.GetExtension(destCatalog);
FileStream TempStream = new FileStream(sTempFileName, FileMode.OpenOrCreate);
BinaryWriter bw = new BinaryWriter(TempStream);
TempBytes = SplitFileReader.ReadBytes(iFileSize);
bw.Write(TempBytes);
bw.Close();
TempStream.Close();
}
SplitFileStream.Close();
SplitFileReader.Close();
suc = true;
}
catch { suc = false; }
return suc;
}
这个思路我感觉可以,但是根据字节怎么得到文本里的内容呢这容易 先用FileStream读取文件长度 然后设定每个文件长度大小为多少
假如每个文件为1M左右
那就是 文件个数 =FileLength/1024/1024;
接下来利用上面的Position 直接定位 第一个文件就是0 到 (1*1024 *1024)字节
先读取这个0- (1*1024 *1024)字节,然后判断(1*1024 *1024)处的两个字节是不是\r\n
代码可以这样
write(0,Position);把大块先写到文件里
while(true)
{
byte[] buff=new byte[1];这里从Position后每次读1个字节
stream.Read(buff,0,1);
write(buff)把读取到的写到文件中
if(buff[0]='\n')
{
break;
}
}
然后直接利用Position即可直接向下读
下面做第二个文件的处理
这是先分块的另外一种是直接
FileStream stream
long MaxLength
FileStream newFile=new 第一个文件
while(true)
{
每次读取两个字节
写入文件块
if(这两个字节是否为\r\n && 是否超出MaxLength)
{
newFile =new (新文件);
}
}
这个思路我感觉可以,但是根据字节怎么得到文本里的内容呢这容易 先用FileStream读取文件长度 然后设定每个文件长度大小为多少
假如每个文件为1M左右
那就是 文件个数 =FileLength/1024/1024;
接下来利用上面的Position 直接定位 第一个文件就是0 到 (1*1024 *1024)字节
先读取这个0- (1*1024 *1024)字节,然后判断(1*1024 *1024)处的两个字节是不是\r\n
代码可以这样
write(0,Position);把大块先写到文件里
while(true)
{
byte[] buff=new byte[1];这里从Position后每次读1个字节
stream.Read(buff,0,1);
write(buff)把读取到的写到文件中
if(buff[0]='\n')
{
break;
}
}
然后直接利用Position即可直接向下读
下面做第二个文件的处理
这是先分块的另外一种是直接
FileStream stream
long MaxLength
FileStream newFile=new 第一个文件
while(true)
{
每次读取两个字节
写入文件块
if(这两个字节是否为\r\n && 是否超出MaxLength)
{
newFile =new (新文件);
}
}
这个思路我感觉可以,但是根据字节怎么得到文本里的内容呢这容易 先用FileStream读取文件长度 然后设定每个文件长度大小为多少
假如每个文件为1M左右
那就是 文件个数 =FileLength/1024/1024;
接下来利用上面的Position 直接定位 第一个文件就是0 到 (1*1024 *1024)字节
先读取这个0- (1*1024 *1024)字节,然后判断(1*1024 *1024)处的两个字节是不是\r\n
代码可以这样
write(0,Position);把大块先写到文件里
while(true)
{
byte[] buff=new byte[1];这里从Position后每次读1个字节
stream.Read(buff,0,1);
write(buff)把读取到的写到文件中
if(buff[0]='\n')
{
break;
}
}
然后直接利用Position即可直接向下读
下面做第二个文件的处理
这是先分块的另外一种是直接
FileStream stream
long MaxLength
FileStream newFile=new 第一个文件
while(true)
{
每次读取两个字节
写入文件块
if(这两个字节是否为\r\n && 是否超出MaxLength)
{
newFile =new (新文件);
}
}
不太明白
fs.Read();
fs.ReadByte();
基本是不会占内存的方法读取 他是直接定位到文件某处读取几个字节,不像其他的类ReadLine()这样是先加载整个文件然后再读取所以造成你的程序无法加载大文件,用FileStream几个字节几个字节读是不会有问题 的所以我上面说的你读两个字节就可以了,
这个思路我感觉可以,但是根据字节怎么得到文本里的内容呢换行符转换成字节byte1 如果等于binaryReader.ReadByte()获得字节,说明就是换行符,就可读取一段数据了
这个思路我感觉可以,但是根据字节怎么得到文本里的内容呢换行符转换成字节byte1 如果等于binaryReader.ReadByte()获得字节,说明就是换行符,就可读取一段数据了
或者将你获得的字节转化成字符串和换行符比较
/// <summary>
/// 分割文件
/// </summary>
/// <param name="fileName">原文件路径</param>
/// <param name="outputFileName">目标文件路径</param>
/// <param name="childFileLong">子文件大小(M)</param>
private void SplitText(string fileName,string outputFileName, long childFileLong)
{
FileStream fileStream = new FileStream(fileName, FileMode.Open);
BinaryReader binaryReader = new BinaryReader(fileStream);
long childFilecount = 1024 * 1024;
long allCount = fileStream.Length; int outputFileNumber = 0;
long startPositon = 0;
binaryReader.BaseStream.Position =startPositon+ childFilecount - 1;
while (binaryReader.BaseStream.Position <= allCount)
{
while (Encoding.Default.GetString(new byte[] { binaryReader.ReadByte() }) != "/n" && binaryReader.BaseStream.Position<allCount-1)
{
binaryReader.BaseStream.Position++;
} FileStream fileStreamOut = new FileStream(outputFileName+outputFileNumber.ToString(), FileMode.CreateNew);
using (BinaryWriter binaryWriter = new BinaryWriter(fileStreamOut))
{
binaryWriter.Write(binaryReader.ReadBytes((int)(binaryReader.BaseStream.Position - startPositon + 1)));
} startPositon = binaryReader.BaseStream.Position + 1;
binaryReader.BaseStream.Position = startPositon + childFilecount - 1;
outputFileNumber++;
} binaryReader.Close();
}
以上代码供你参考,没有测试。如果子文件也比较大,为了避免占用大量内存空间,
binaryWriter.Write(binaryReader.ReadBytes((int)(binaryReader.BaseStream.Position - startPositon + 1)));这部分需要再进行处理,分割成更小的片段读取写入。
while (binaryReader.BaseStream.Position <= allCount)
{
while (Encoding.Default.GetString(new byte[] { binaryReader.ReadByte() }) != "/n" && binaryReader.BaseStream.Position<allCount-1)
{
binaryReader.BaseStream.Position++;
}这两个循环次数太多了,我得到的文件allCount 长度是13亿多,但是binaryReader.BaseStream.Position的position值只有100多万这样也很慢