C# split big file into small files as, and merge the small files into big one

FredGrit發表於2024-09-01
namespace ConsoleApp59
{
    internal class Program
    {
        static string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
        static void Main(string[] args)
        {
            string filePath = @"D:\Software\WallStreetWolf\WallStreetWolf.mkv";
            int chunkSize = 100000000;
            SplitLargeFile(filePath, chunkSize);
            MergeSmallFilesIntoOne(chunkSize);
            Console.WriteLine("Finished!");            
        }

        static void MergeSmallFilesIntoOne(int chunkSize = 100000000)
        {
            var mkvFiles = Directory.GetFiles(path, "*.mkv")?.OrderBy(x => new FileInfo(x).CreationTime)?.ToList();
            using (var newFs = File.Create("WallStreetWolf.mkv"))
            {
                int filesCount = mkvFiles.Count();
                for(int i=0;i<filesCount; i++)
                {
                    string kvFile=mkvFiles[i];
                    using (var largeFileStream = File.OpenRead(kvFile))
                    {
                        var buffer = new byte[chunkSize];
                        int bytesRead;
                        while ((bytesRead = largeFileStream.Read(buffer, 0, chunkSize)) > 0)
                        {
                            newFs.Write(buffer, 0, bytesRead);
                            Console.WriteLine(kvFile);
                        }
                    }
                }
            }
            Console.WriteLine("Finised in MergeSmallFilesIntoOne!\n\n\n");
        }

        static void SplitLargeFile(string filePath, int chunkSize)
        {
            int idx = 0;
            
            string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath);
            string extension = System.IO.Path.GetExtension(filePath);
            using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                var buffer = new byte[chunkSize];
                int bytesRead;
                while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0)
                {
                    byte[] destArray = new byte[bytesRead];
                    Array.Copy(buffer, destArray, bytesRead);
                    string splitFile = $"{fileName}_{idx++}{extension}";
                    using (FileStream destStream = new FileStream(splitFile, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                    {
                        using (MemoryStream ms = new MemoryStream(destArray))
                        {
                            ms.WriteTo(destStream);
                            Console.WriteLine(splitFile);
                        }
                    }
                }
            }
            Console.WriteLine("Finised in SplitLargeFile!\n\n\n");
        }
    }
}

To be cautious,when merge split small bulks into bigger one,must order by created time as below

var mkvFiles = Directory.GetFiles(path, "*.mkv")?.OrderBy(x => new FileInfo(x).CreationTime)?.ToList();

var mkvFiles = Directory.GetFiles(path, "*.mkv")?.OrderBy(x => new FileInfo(x).CreationTime)?.ToList();
using (var newFs = File.Create("WallStreetWolf.mkv"))
{
    int filesCount = mkvFiles.Count();
    for(int i=0;i<filesCount; i++)
    {
        string kvFile=mkvFiles[i];
        using (var largeFileStream = File.OpenRead(kvFile))
        {
            var buffer = new byte[chunkSize];
            int bytesRead;
            while ((bytesRead = largeFileStream.Read(buffer, 0, chunkSize)) > 0)
            {
                newFs.Write(buffer, 0, bytesRead);
                Console.WriteLine(kvFile);
            }
        }
    }
}

相關文章