Search code examples
c#.netzip

Generate multiple smaller zip files from Folder c#


I have a folder which contains files which i havce to copy over a slow network.

I generate the zip as follows.

    string path = @".\Files";
    string zipPath = @".\transfer.zip";

    ZipFile.CreateFromDirectory(path , zipPath);

The zip file that is generated is 10GB, and to copy that single file is slow. I wanted to generate zip files for the folder that are maximum 1GB so in this case it would generate 10.

Is there a way to do this in C#


Solution

  • I just threw this together and tested it. It's a bit rough but I'm just taking a short break from work. Be aware it that it tracks the raw file sizes and not the zipped file size. So it'll take up to 1GB of raw files and convert them and continue on with the rest of the files.

            //maximum size in bytes (1gb)
            long maxSize = 1073741824;                                      
            string path = @".\Files";
            string zipPath = @".\transfer.zip";
            //keep track of sum of sizes of raw files to be zipped.
            long currentSize = 0;
            //get list of files to iterate through.
            string[] filesToCompress = Directory.GetFiles(path, "*.*");
            //declare file counter so you don't duplicate filenames.
            int fileCounter = 1;
            //create empty list to store file paths to be zipped.
            List<string> zipMe = new List<string>();
            string zipName = string.Empty;
            foreach (string file in filesToCompress)
            {
                zipName = "myfile_" + fileCounter + ".zip";
                FileInfo f = new FileInfo(file);
                if ((f.Length + currentSize) >= maxSize)
                {
                    //create zip file
                    using (ZipArchive newFile = ZipFile.Open(zipPath+zipName, ZipArchiveMode.Create))
                    {
                        foreach (string item in zipMe)
                        {
                            newFile.CreateEntryFromFile(item, item.Replace(path + "\\", ""));
                        }
                    }
                    //clear the list
                    zipMe.Clear();
                    //add the file that would have put it over the file size limit to the beginning of the next list.
                    zipMe.Add(f.FullName);
                    //increase counter for filename.
                    fileCounter++;
                    //set currentsize equal to the file's size we just added to the list.
                    currentSize = f.Length;
                }
                else
                {
                    //Haven't hit 1gb yet...add file's length to current length as well as add it to the list and keep on going!
                    currentSize = currentSize + f.Length;
                    zipMe.Add(f.FullName);
                }               
            }
            //Loop is done, let's clear up any files left over in the list that didne't exceed our file size limit.
            if (zipMe.Count > 0)
            {
                using (ZipArchive newFile = ZipFile.Open(zipPath + zipName, ZipArchiveMode.Create))
                {
                    foreach (string item in zipMe)
                    {
                        newFile.CreateEntryFromFile(item, item.Replace(path + "\\", ""));
                    }
                }
            }