|
TXT文件,3.2g,如何把这个文件分割成若干个小文件? 分割不能切开某一个时间线的数据。 11:11,1,2,3,4,5,6,7,8,9,0 例如上面的数据,如何按行分割,要求一行时间线的数据不能切开(也就是换行分割)? 最好给个源码看看,我现在分割可以但是没根据换行分割,而且分割的时候会超时 |
|
|
你就用换行符分割啊!超时估计是你的文档太大,但是应该还在运行的.你可以看分割后的文档有没有增加
|
|
|
每行长度一样?
那就计算分割文件SIZE,直接二进制操作就快了 |
|
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不知道行不行.
|
|
|
sr.ReadLine()
|
|
|
20分 |
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++;
}
}
|
|
看来执行时间短不了
3.2G 复制黏贴一下 就要多长时间啊 还要分割出来。 |
|
|
正常的分割要不了多久,但是根据换行分割就不知道了 |
|
|
效果是达到了,但是速度貌似有点慢啊 |
|
|
没有程序,说说我的思路:
使用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>
/// 分割大文件成独立小文件并保存小文件至指定目录 /// </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读取文件长度 然后设定每个文件长度大小为多少 另外一种是直接 } |
|
|
就这个你用FileStream 的类
fs.Read(); fs.ReadByte(); 基本是不会占内存的方法读取 他是直接定位到文件某处读取几个字节, 不像其他的类ReadLine()这样是先加载整个文件然后再读取 所以造成你的程序无法加载大文件,用FileStream几个字节几个字节读是不会有问题 的所以我上面说的你读两个字节就可以了, |
|
|
我根据你第一个方法读取我的byte字节数组,读不到换行符,也读不到内容,只是一下字节数字
|
|
|
换行符转换成字节byte1 如果等于binaryReader.ReadByte()获得字节,说明就是换行符,就可读取一段数据了 |
|
|
或者将你获得的字节转化成字符串和换行符比较 |
|
|
10分 |
/// <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();
}
|
|
以上代码供你参考,没有测试。如果子文件也比较大,为了避免占用大量内存空间, |
|
|
直接用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多万这样也很慢 |
|
|
才30分呀,要是200分就给你实现一个 |
|
|
正常分割什么意思?先分成几个适当的文件,在按行处理
|
|
|
using System;
using System.IO; using System.Text; namespace File_Read static void ReadData(string sourcePath,string targetDirectory) while (line != null) static void WriteData(string str, string path) |
|