在要求输入邮箱的文本域,请填写真实的邮件地址。非真实邮件地址,将收不到回复信息。

C#实现大文本文件切割/分割

C# 清风 80℃ 0评论

因某些原因,需要打开日志进行排查,本来是很简单的事情,当看到日之后就觉得力不从心。日志文件太大了,将近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#实现大文本文件切割/分割

喜欢 (0)or分享 (0)
支付宝扫码打赏 微信打赏
发表我的评论
取消评论

CAPTCHA Image
Reload Image
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址