因某些原因,需要打开日志进行排查,本来是很简单的事情,当看到日之后就觉得力不从心。日志文件太大了,将近5G,自己电脑打不开这种大文件。一开始就想到了文件分割,然后就再网上找一些分割工具,找了几个分割工具杀毒软件都报毒。找工具也真是个麻烦的事情,找到半天没有见到一个合适的。其中一个不报毒(主动查杀了一次)的,双击后也打不开,这个时候我就怀疑自己中招(中毒)了,到底有没有中招暂时不太清楚,所以赶紧利用杀毒软件查杀病毒。在查杀病毒的期间自己就动手使用C#写一个简单的文本文件分割工具。这里就记录一下.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
namespace TxtFileCutApart
{
class Program
{
static void Main(string[] args)
{
if (args.Length < 3)
{
Console.WriteLine("缺少参数。");
return;
}
if (!File.Exists(args[0]))
{
Console.WriteLine("分割文件不存在");
return;
}
if (!Directory.Exists(args[1]))
{
Console.WriteLine("分割目录不存在");
return;
}
long size = Convert.ToInt64(args[2]);
List types = new List() {"size","count","row" };
Dictionary dicFileCut = new Dictionary() { {"size",new TxtFileCutApartFileSize() }, { "count", new TxtFileCutApartFileCount() } , { "row", new TxtFileCutApartRows() } };
string type =types[0];
if (args.Length == 4&&types.Contains(args[3]))
{
type =args[3];
}
Console.WriteLine("开始分割,请稍候……");
Stopwatch st = new Stopwatch();
TxtFileCutApart txtFileCut = dicFileCut[type];
st.Start();
txtFileCut.FileCut(args[0],args[1],size);
st.Stop();
Console.WriteLine($"完成,耗时:{st.ElapsedMilliseconds/1000}s");
}
}
public abstract class TxtFileCutApart
{
public abstract void FileCut(string sourcePath, string targetFolder,long size);
}
public class TxtFileCutApartFileCount : TxtFileCutApart
{
public override void FileCut(string sourcePath, string targetFolder, long fileCount)
{
if (fileCount <= 0)
{
return;
}
FileInfo fileInfo = new FileInfo(sourcePath);
string fileName = fileInfo.Name.Replace(fileInfo.Extension, "");
long fileLength = fileInfo.Length;
FileStream fsRead = new FileStream(sourcePath, FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryReader br = new BinaryReader(fsRead);
int defaultBurrerLength = 1024 * 1024;
long fileSizeLength = Convert.ToInt64((Math.Ceiling(fileLength / Convert.ToDouble(fileCount))));
byte[] buffer = new byte[defaultBurrerLength];
int readLength = 0;
int fileIndex = 1;
long readFileLength = 0;
while (readFileLength < fileLength)
{
string writeFile = Path.Combine(targetFolder, $"{fileName}_{fileIndex}{fileInfo.Extension}");
FileStream fsWrite = new FileStream(writeFile, FileMode.CreateNew, FileAccess.Write);
BinaryWriter bw = new BinaryWriter(fsWrite);
long singleFileLength = 0;
while ((readLength = br.Read(buffer, 0, buffer.Length)) > 0)
{
bw.Write(buffer, 0, readLength);
readFileLength += readLength;
singleFileLength += readLength;
if (singleFileLength >= fileSizeLength)
{
bw?.Close();
bw?.Dispose();
fsWrite?.Close();
fsWrite?.Dispose();
break;
}
}
bw?.Close();
bw?.Dispose();
fsWrite?.Close();
fsWrite?.Dispose();
fileIndex++;
}
br?.Close();
br?.Dispose();
fsRead?.Close();
fsRead.Dispose();
}
}
public class TxtFileCutApartFileSize : TxtFileCutApart
{
public override void FileCut(string sourcePath, string targetFolder, long fileSize)
{
if (fileSize <= 0)
{
return;
}
FileInfo fileInfo = new FileInfo(sourcePath);
string fileName = fileInfo.Name.Replace(fileInfo.Extension, "");
FileStream fsRead = new FileStream(sourcePath, FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryReader br = new BinaryReader(fsRead);
int defaultBurrerLength = 1024 * 1024;
long fileSizeLength = fileSize * defaultBurrerLength;
byte[] buffer = new byte[defaultBurrerLength];
int readLength = 0;
int fileIndex = 1;
long fileLength = fileInfo.Length;
long readFileLength = 0;
while (readFileLength < fileLength)
{
string writeFile = Path.Combine(targetFolder, $"{fileName}_{fileIndex}{fileInfo.Extension}");
FileStream fsWrite = new FileStream(writeFile, FileMode.CreateNew, FileAccess.Write);
BinaryWriter bw = new BinaryWriter(fsWrite);
long singleFileLength = 0;
while ((readLength = br.Read(buffer, 0, buffer.Length)) > 0)
{
bw.Write(buffer, 0, readLength);
readFileLength += readLength;
singleFileLength += readLength;
if (singleFileLength >= fileSizeLength)
{
bw?.Close();
bw?.Dispose();
fsWrite?.Close();
fsWrite?.Dispose();
break;
}
}
bw?.Close();
bw?.Dispose();
fsWrite?.Close();
fsWrite?.Dispose();
fileIndex++;
}
br?.Close();
br?.Dispose();
fsRead?.Close();
fsRead.Dispose();
}
}
public class TxtFileCutApartRows: TxtFileCutApart
{
public override void FileCut(string sourcePath, string targetFolder, long row)
{
if (row <= 0)
{
return;
}
FileInfo fileInfo = new FileInfo(sourcePath);
string fileName = fileInfo.Name.Replace(fileInfo.Extension, "");
string lineData = "";
StreamReader sr = new StreamReader(sourcePath);
StreamWriter sw = null;
long readEowIndex = 1, index = 1;
while ((lineData = sr.ReadLine()) != null)
{
if (sw == null || readEowIndex >= row)
{
sw?.Close();
sw?.Dispose();
string _fileName = Path.Combine(targetFolder, $"{fileName}_{index}{fileInfo.Extension}");
sw = new StreamWriter(_fileName);
readEowIndex = 1;
index++;
}
if (row >= readEowIndex)
{
sw.WriteLine(lineData);
sw.Flush();
readEowIndex++;
}
}
sw?.Close();
sw?.Dispose();
sr?.Close();
sr.Dispose();
}
}
}
小的切割工具可以按照大小(兆)、按照文件数量、按照行来进行分割。
dotnet TxtFileCutApart.dll 文件路径 分割后保存目录 数值 分割类型
具体使用方法,如下图所示:
源码下载
C#超大文本文件分割小工具
转载请注明:清风亦平凡 » C#实现大文本文件切割/分割