I have one example where all the files in the folder are zipped but not the folder itself .[This code is from MSDN]
using System;
using System.IO;
using System.IO.Compression;
namespace zip
{
public class Program
{
public static void Main()
{
string directoryPath = #"c ------------------------------------------------------------------------ :\users\public\reports";
DirectoryInfo directorySelected = new DirectoryInfo(directoryPath);
foreach (FileInfo fileToCompress in directorySelected.GetFiles())
{
Compress(fileToCompress);
}
foreach (FileInfo fileToDecompress in directorySelected.GetFiles("*.gz"))
{
Decompress(fileToDecompress);
}
}
public static void Compress(FileInfo fileToCompress)
{
using (FileStream originalFileStream = fileToCompress.OpenRead())
{
if ((File.GetAttributes(fileToCompress.FullName) & FileAttributes.Hidden) != FileAttributes.Hidden & fileToCompress.Extension != ".gz")
{
using
(FileStream compressedFileStream = File.Create(fileToCompress.FullName + ".gz"))
{
using (GZipStream compressionStream = new GZipStream(compressedFileStream, CompressionMode.Compress))
{
originalFileStream.CopyTo(compressionStream);
Console.WriteLine("Compressed {0} from {1} to {2} bytes.", fileToCompress.Name, fileToCompress.Length.ToString(), compressedFileStream.Length.ToString());
}
}
}
}
}
public static void Decompress(FileInfo fileToDecompress)
{
using (FileStream originalFileStream = fileToDecompress.OpenRead())
{
string currentFileName = fileToDecompress.FullName;
string newFileName = currentFileName.Remove(currentFileName.Length - fileToDecompress.Extension.Length);
using (FileStream decompressedFileStream = File.Create(newFileName))
{
using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress))
{
decompressionStream.CopyTo(decompressedFileStream);
Console.WriteLine("Decompressed: {0}", fileToDecompress.Name);
}
}
}
}
}
}
I don't think you can zip a complete folder using System.IO.Compression, you can only compress files inside the folder. You can use DotNetZip instead. It is a 100% managed code library that can be used in any .NET application - Console, Winforms, WPF, ASP.NET, Sharepoint, Web services apps, and so on.
Download developer's kit package from http://dotnetzip.codeplex.com/Release/ProjectReleases.aspx.
Reference necessaries including DotNetZip DLL in your application and do follows:
string[] MainDirs = Directory.GetDirectories(""c:\users\public\reports");
for (int i = 0; i < MainDirs.Length; i++)
{
using (ZipFile zip = new ZipFile())
{
zip.UseUnicodeAsNecessary = true;
zip.AddDirectory(MainDirs[i]);
zip.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression;
zip.Comment = "This zip was created at " + System.DateTime.Now.ToString("G");
zip.Save(string.Format("test{0}.zip", i));
}
}
Hope this helps,
Thanks
Related
I want to create a .zip file in C# and after that I want to put a xml file in it.
This is what I tried but it doesn't work.
I have a folder like, archieve -> 2040 -> and here I want to create the archieve
private void WriteXmlArchieveProductOnDisk(string identifier, string pathInFolder, byte[] xmlFile)
{
string folderName = Path.Combine("Resources", pathInFolder, _baseService.CurrentCompanyId().ToString());
string pathToSave = Path.Combine(Directory.GetCurrentDirectory(), folderName);
if (!Directory.Exists(pathToSave))
{
Directory.CreateDirectory(pathToSave);
}
string fileNameWithoutExtension = $"{Guid.NewGuid()}_{identifier}";
string fileNameWithExtension = $"{fileNameWithoutExtension}.xml";
List<string> existing = Directory.EnumerateFiles(pathToSave).Where(file => Path.GetFileNameWithoutExtension(file) == fileNameWithoutExtension).ToList();
if (existing.Count > 0)
{
foreach (var file in existing)
{
FileD.Delete(file);
}
}
using (var ms = new MemoryStream())
{
using (var archive = new ZipArchive(ms, ZipArchiveMode.Create, true))
{
var zipArchiveEntry = archive.CreateEntry(fileNameWithExtension);
using (var entryStream = zipArchiveEntry.Open())
using (var fileToCompressStream = new StreamWriter(entryStream))
{
fileToCompressStream.Write(xmlFile);
}
}
using (var fileStream = new FileStream($"{pathToSave}", FileMode.Create))
{
ms.Seek(0, SeekOrigin.Begin);
ms.CopyTo(fileStream);
}
}
}
I am trying to unzip .gz files using GZipStream. It will only exctract 12kb of the file but if I use winzip or 7zip to unzip the .gz file the extracted file should be 753kb. See the code below that I am using, any pointers on where I am going wrong?
public bool StartLibZipExtraction()
{
bool returnResult = false;
try
{
DirectoryInfo directorySelected = new DirectoryInfo(m_ProjectPath);
foreach (FileInfo fileToDecompress in directorySelected.GetFiles("*.gz"))
{
// check if this is the file to UNZIP
if (fileToDecompress.Name.Equals(m_ZipFileName))
{
returnResult = true; // unzip successful
Agent.LogInfo("~~~ Unzipping file: " + fileToDecompress.ToString() + " ~~~");
Decompress(fileToDecompress);
break;
}
}
}
catch(Exception e)
{
Agent.LogInfo("*** StartLibZipExtraction() Error: " + e.Message + " ***");
return false;
}
return returnResult;
}
public void Decompress(FileInfo fileToDecompress)
{
using (FileStream originalFileStream = fileToDecompress.OpenRead())
{
string currentFileName = fileToDecompress.FullName;
string newFileName = currentFileName.Remove(currentFileName.Length - fileToDecompress.Extension.Length);
using (FileStream decompressedFileStream = File.Create(newFileName))
{
using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress))
{
decompressionStream.CopyTo(decompressedFileStream);
Agent.LogInfo(decompressionStream.ToString());
Agent.LogInfo("Decompressed: {0}" + fileToDecompress.Name);
}
}
}
}
Here is my problem, i'm trying to make minecraft classic server and i'm using text system to make allow list for each map, problem is text system makes a file for each map and we got around 15k maps in total, so if 1k of players add allow list to their maps, it would be hard to upload / move server to another host. i want to make a zip file in main folder of my software and add each text file to it and also making it readable with system, i want to know how to read a file from GZip, and how to compress files also.
Thanks
Here is my very easy working code. No temporary file
using (FileStream reader = File.OpenRead(filePath))
using (GZipStream zip = new GZipStream(reader, CompressionMode.Decompress, true))
using (StreamReader unzip = new StreamReader(zip))
while(!unzip.EndOfStream)
ReadLine(unzip.ReadLine());
If you want to avoid creating temporary files, you can use this:
using (Stream fileStream = File.OpenRead(filePath),
zippedStream = new GZipStream(fileStream, CompressionMode.Decompress))
{
using (StreamReader reader = new StreamReader(zippedStream))
{
// work with reader
}
}
Details on how to use GZip to compress and decompress. After decompression, you can use the StreamReader() class to read the contents of the file (.NET 4.0).
using System;
using System.IO;
using System.IO.Compression;
namespace zip
{
public class Program
{
public static void Main()
{
string directoryPath = #"c:\users\public\reports";
DirectoryInfo directorySelected = new DirectoryInfo(directoryPath);
foreach (FileInfo fileToCompress in directorySelected.GetFiles())
{
Compress(fileToCompress);
}
foreach (FileInfo fileToDecompress in directorySelected.GetFiles("*.gz"))
{
Decompress(fileToDecompress);
}
}
public static void Compress(FileInfo fileToCompress)
{
using (FileStream originalFileStream = fileToCompress.OpenRead())
{
if ((File.GetAttributes(fileToCompress.FullName) & FileAttributes.Hidden) != FileAttributes.Hidden & fileToCompress.Extension != ".gz")
{
using (FileStream compressedFileStream = File.Create(fileToCompress.FullName + ".gz"))
{
using (GZipStream compressionStream = new GZipStream(compressedFileStream, CompressionMode.Compress))
{
originalFileStream.CopyTo(compressionStream);
Console.WriteLine("Compressed {0} from {1} to {2} bytes.",
fileToCompress.Name, fileToCompress.Length.ToString(), compressedFileStream.Length.ToString());
}
}
}
}
}
public static void Decompress(FileInfo fileToDecompress)
{
using (FileStream originalFileStream = fileToDecompress.OpenRead())
{
string currentFileName = fileToDecompress.FullName;
string newFileName = currentFileName.Remove(currentFileName.Length - fileToDecompress.Extension.Length);
using (FileStream decompressedFileStream = File.Create(newFileName))
{
using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress))
{
decompressionStream.CopyTo(decompressedFileStream);
Console.WriteLine("Decompressed: {0}", fileToDecompress.Name);
}
}
}
}
}
}
Source
I want compress/decompress directories without any dll.
I use this code for compress a file with GzipStream.
public static void Compress(FileInfo fileToCompress)
{
using (FileStream originalFileStream = fileToCompress.OpenRead())
{
if ((File.GetAttributes(fileToCompress.FullName) & FileAttributes.Hidden) != FileAttributes.Hidden & fileToCompress.Extension != ".gz")
{
using (FileStream compressedFileStream = File.Create(fileToCompress.FullName + ".gz"))
{
using (GZipStream compressionStream = new GZipStream(compressedFileStream, CompressionMode.Compress))
{
originalFileStream.CopyTo(compressionStream);
Console.WriteLine("Compressed {0} from {1} to {2} bytes.",
fileToCompress.Name, fileToCompress.Length.ToString(), compressedFileStream.Length.ToString());
}
}
}
}
}
I use this link for compress directory. but don't work for me :(
From what I can tell, you can't compress an entire directory to a single gz file. You end up with multiple gz files.
You can package the directory up as a .Tar file and then use gZip on the tar file.
Which would require using a library such as SharpZipLib. You can install the library from the Manage NuGet Packages menu.
DirectoryInfo directoryOfFilesToBeTarred = new DirectoryInfo(#"c:\tar\start");
FileInfo[] filesInDirectory = directoryOfFilesToBeTarred.GetFiles();
String tarArchiveName = #"c:\tar\mytararchive.tar.gz";
using (Stream targetStream = new GZipOutputStream(File.Create(tarArchiveName)))
{
using (TarArchive tarArchive = TarArchive.CreateOutputTarArchive(targetStream, TarBuffer.DefaultBlockFactor))
{
foreach (FileInfo fileToBeTarred in filesInDirectory)
{
TarEntry entry = TarEntry.CreateEntryFromFile(fileToBeTarred.FullName);
tarArchive.WriteEntry(entry, true);
}
}
}
Source:
https://dotnetcodr.com/2015/02/04/packing-and-unpacking-files-using-tar-archives-in-net/
OR
You can zip the directory in pure .NET 3.0. Using SharpZipLib may not be desirable due to the modified GPL license.
First, you will need a reference to WindowsBase.dll.
This code will open or create a zip file, create a directory inside, and place the file in that directory. If you want to zip a folder, possibly containing sub-directories, you could loop through the files in the directory and call this method for each file. Then, you could depth-first search the sub-directories for files, call the method for each of those and pass in the path to create that hierarchy within the zip file.
public void AddFileToZip(string zipFilename, string fileToAdd, string destDir)
{
using (Package zip = System.IO.Packaging.Package.Open(zipFilename, FileMode.OpenOrCreate))
{
string destFilename = "." + destDir + "\\" + Path.GetFileName(fileToAdd);
Uri uri = PackUriHelper.CreatePartUri(new Uri(destFilename, UriKind.Relative));
if (zip.PartExists(uri))
{
zip.DeletePart(uri);
}
PackagePart part = zip.CreatePart(uri, "", CompressionOption.Normal);
using (FileStream fileStream = new FileStream(fileToAdd, FileMode.Open, FileAccess.Read))
{
using (Stream dest = part.GetStream())
{
CopyStream(fileStream, dest);
}
}
}
}
destDir could be an empty string, which would place the file directly in the zip.
Sources:
https://weblogs.asp.net/jongalloway/creating-zip-archives-in-net-without-an-external-library-like-sharpziplib
https://weblogs.asp.net/albertpascual/creating-a-folder-inside-the-zip-file-with-system-io-packaging
I want to compress a file and a directory in C#. I found some solution in Internet but they are so complex and I couldn't run them in my project. Can anybody suggest me a clear and effective solution?
You could use GZipStream in the System.IO.Compression namespace
.NET 2.0.
public static void CompressFile(string path)
{
FileStream sourceFile = File.OpenRead(path);
FileStream destinationFile = File.Create(path + ".gz");
byte[] buffer = new byte[sourceFile.Length];
sourceFile.Read(buffer, 0, buffer.Length);
using (GZipStream output = new GZipStream(destinationFile,
CompressionMode.Compress))
{
Console.WriteLine("Compressing {0} to {1}.", sourceFile.Name,
destinationFile.Name, false);
output.Write(buffer, 0, buffer.Length);
}
// Close the files.
sourceFile.Close();
destinationFile.Close();
}
.NET 4
public static void Compress(FileInfo fi)
{
// Get the stream of the source file.
using (FileStream inFile = fi.OpenRead())
{
// Prevent compressing hidden and
// already compressed files.
if ((File.GetAttributes(fi.FullName)
& FileAttributes.Hidden)
!= FileAttributes.Hidden & fi.Extension != ".gz")
{
// Create the compressed file.
using (FileStream outFile =
File.Create(fi.FullName + ".gz"))
{
using (GZipStream Compress =
new GZipStream(outFile,
CompressionMode.Compress))
{
// Copy the source file into
// the compression stream.
inFile.CopyTo(Compress);
Console.WriteLine("Compressed {0} from {1} to {2} bytes.",
fi.Name, fi.Length.ToString(), outFile.Length.ToString());
}
}
}
}
}
http://msdn.microsoft.com/en-us/library/ms404280.aspx
I'm adding this answer as I've found an easier way than any of the existing answers:
Install DotNetZip DLLs in your solution (easiest way is to install the package from nuget)
Add a reference to the DLL.
Import the namespace by adding: using Ionic.Zip;
Zip your file
Code:
using (ZipFile zip = new ZipFile())
{
zip.AddFile("C:\test\test.txt");
zip.AddFile("C:\test\test2.txt");
zip.Save("C:\output.zip");
}
If you don't want the original folder structure mirrored in the zip file, then look at the overrides for AddFile() and AddFolder() etc.
For .Net Framework 4.5 this is the most clear example I found:
using System;
using System.IO;
using System.IO.Compression;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
string startPath = #"c:\example\start";
string zipPath = #"c:\example\result.zip";
string extractPath = #"c:\example\extract";
ZipFile.CreateFromDirectory(startPath, zipPath);
ZipFile.ExtractToDirectory(zipPath, extractPath);
}
}
}
You'll need to add a reference to System.IO.Compression.FileSystem
From: https://learn.microsoft.com/en-us/dotnet/standard/io/how-to-compress-and-extract-files
There is a built-in class in System.IO.Packaging called the ZipPackage:
http://msdn.microsoft.com/en-us/library/system.io.packaging.zippackage(v=vs.100).aspx
http://www.icsharpcode.net/opensource/sharpziplib/
You can just use ms-dos command line program compact.exe.
Look on a parameters compact.exe in cmd and start this process using .NET method Process.Start().
Using DotNetZip http://dotnetzip.codeplex.com/, there's an AddDirectory() method on the ZipFile class that does what you want:
using (var zip = new Ionic.Zip.ZipFile())
{
zip.AddDirectory("DirectoryOnDisk", "rootInZipFile");
zip.Save("MyFile.zip");
}
Bonne continuation...
just use following code for compressing a file.
public void Compressfile()
{
string fileName = "Text.txt";
string sourcePath = #"C:\SMSDBBACKUP";
DirectoryInfo di = new DirectoryInfo(sourcePath);
foreach (FileInfo fi in di.GetFiles())
{
//for specific file
if (fi.ToString() == fileName)
{
Compress(fi);
}
}
}
public static void Compress(FileInfo fi)
{
// Get the stream of the source file.
using (FileStream inFile = fi.OpenRead())
{
// Prevent compressing hidden and
// already compressed files.
if ((File.GetAttributes(fi.FullName)
& FileAttributes.Hidden)
!= FileAttributes.Hidden & fi.Extension != ".gz")
{
// Create the compressed file.
using (FileStream outFile =
File.Create(fi.FullName + ".gz"))
{
using (GZipStream Compress =
new GZipStream(outFile,
CompressionMode.Compress))
{
// Copy the source file into
// the compression stream.
inFile.CopyTo(Compress);
Console.WriteLine("Compressed {0} from {1} to {2} bytes.",
fi.Name, fi.Length.ToString(), outFile.Length.ToString());
}
}
}
}
}
}
Use http://dotnetzip.codeplex.com/ to ZIP files or directory, there is no builtin class to do it directly in .NET
Source code taken from MSDN that is compatible to .Net 2.0 and above
public static void CompressFile(string path)
{
FileStream sourceFile = File.OpenRead(path);
FileStream destinationFile = File.Create(path + ".gz");
byte[] buffer = new byte[sourceFile.Length];
sourceFile.Read(buffer, 0, buffer.Length);
using (GZipStream output = new GZipStream(destinationFile,
CompressionMode.Compress))
{
Console.WriteLine("Compressing {0} to {1}.", sourceFile.Name,
destinationFile.Name, false);
output.Write(buffer, 0, buffer.Length);
}
// Close the files.
sourceFile.Close();
destinationFile.Close();
}