I'm collecting all my files in a target directory and adding them to a zip folder. Once this zip is made and no more files need adding to it, I want to move this zip folder to another location.
Here is my code for doing all of the above:
var targetFolder = Path.Combine(ConfigurationManager.AppSettings["targetFolder"], "Inbound");
var archiveFolder = ConfigurationManager.AppSettings["ArchiveFolder"];
// get files
var files = Directory.GetFiles(targetFolder)
.Select(f => new FileInfo(f))
.ToList();
// places files into zip
using (var zip = ZipFile.Open("file.zip", ZipArchiveMode.Create))
{
foreach (var file in files)
{
var entry = zip.CreateEntry(file.Name);
entry.LastWriteTime = DateTimeOffset.Now;
using (var stream = File.OpenRead(file.ToString()))
using (var entryStream = entry.Open())
stream.CopyTo(entryStream);
}
}
// move the zip file
File.Move("file.zip", archiveFolder );
Where I'm falling down is the moving of the zip folder. When my code gets to File.Move I get an error telling me it can not create something that already exists. This happen even when I hard code in my archive folder location instead of getting it from my config.
What am I doing wrong with this?
You need to specify the destination file name as well as directory:
File.Move("file.zip", Path.Combine(archiveFolder, "file.zip"));
Related
I have one ZIP file named abc.ZIP
Inside ZIP folder structure is as below:
--abc
---pqr
----a
----b
----c
I want to extract this ZIP at D:/folder_name
But i want to extract only folder and its content named a,b,c. Also folder names are not fixed. I dont want to extract root folder abc and its child folder pqr.
I used following code but its not working:
using (ZipFile zipFile = ZipFile.Read(#"temp.zip"))
{
foreach (ZipEntry entry in zipFile.Entries)
{
entry.Extract(#"D:/folder_name");
}
}
The following should work, but I'm not sure, if it's the best option.
string rootPath = "abc/pqr/";
using (ZipFile zipFile = ZipFile.Read(#"abc.zip"))
{
foreach (ZipEntry entry in zipFile.Entries)
{
if (entry.FileName.StartsWith(rootPath) && entry.FileName.Length > rootPath.Length)
{
string path = Path.Combine(#"D:/folder_name", entry.FileName.Substring(rootPath.Length));
if (entry.IsDirectory)
{
Directory.CreateDirectory(path);
}
else
{
using (FileStream stream = new FileStream(path, FileMode.Create))
entry.Extract(stream);
}
}
}
}
Other option would be to extract the complete file in a temporary directory and move the sub directories to your target directory.
I am trying to zip together all folders and their contents into a zip file. From what I have researched (through StackOverflow and Microsoft), Directory.CreateDirectory(Path) should create the given directory. However, my ZipFile is showing up empty.
For example, I have a folder (C:\Users\smelmo\Desktop\test) with the subfolders (0001, 0002) in it. Within 0001 and 0002 are other documents. I am wanting to zip 0001 and 0002 together within the test folder. This is what I have so far:
// Open the directory of the target folder
using (ZipArchive archive = ZipFile.Open(strZipPath, ZipArchiveMode.Create))
{
// Grab each directory within the target folder
foreach (var directoryName in Directory.GetDirectories(strStartPath))
{
// Add each directory to the ZipFile
Directory.CreateDirectory(directoryName);
}
}
This does not produce anything. HOWEVER, I also have code that will grab ALL files within the subfolders and place them in the ZipFile.
// Open the directory of the target folder
using (ZipArchive archive = ZipFile.Open(strZipPath, ZipArchiveMode.Create))
{
// Grab each directory within the target folder
foreach (var directoryName in Directory.GetDirectories(strStartPath))
{
//Grab all files in each directory
foreach (var filePath in Directory.GetFiles(directoryName))
{
var fileName = Path.GetFileName(#filePath);
// Place each directory and its repsective files in the zip file
var entry = archive.CreateEntryFromFile(filePath, fileName);
}
}
}
But this does not place subfolders 0001 and 0002 in it, just the CONTENTS of 0001 and 0002. I am wanting 0001 and 0002 and their respective contents.
Edited:
If you are looking for more control, you can just create a function that adds files to a zip archive. You can then use recursion to add any subfolders and files.
First you can define a function that accepts a zip archive to add files to:
public void AddFolderToZip(ZipArchive archive, string rootPath, string path, bool recursive)
{
foreach (var filePath in Directory.GetFiles(path))
{
//Remove root path portion from file path, so entry is relative to root
string entryName = filePath.Replace(rootPath, "");
entryName = entryName.StartsWith("\\") ? entryName.Substring(1) : entryName;
var entry = archive.CreateEntryFromFile(filePath, entryName);
}
if (recursive)
{
foreach (var subPath in Directory.GetDirectories(path))
{
AddFolderToZip(archive, rootPath, subPath, recursive);
}
}
}
Then you can call it using the following code:
string strStartPath = #"C:\Test\zip";
string strZipPath = #"C:\Test\output.zip";
ZipArchive archive = ZipFile.Open(strZipPath, ZipArchiveMode.Create);
bool recursive = true;
foreach (var directoryPath in Directory.GetDirectories(strStartPath))
{
AddFolderToZip(archive, strStartPath, directoryPath, recursive);
}
archive.Dispose();
This code adds each directory it finds in a top level directory. And for each directory it finds, it will use recursion to add any subdirectories or files found within those.
I am working on a project where I need to get Zip files from S3 Bucket.
I was able to copy these files one at a time to my EC2 instance using
foreach (S3Object o in response.S3Objects)
{
GetObjectRequest requests = new GetObjectRequest();
requests.BucketName = "mybucket";
requests.Key = o.Key;
GetObjectResponse responses = client.GetObject(requests);
responses.WriteResponseStreamToFile(#"D:\myfile.zip");
Console.WriteLine("{0}\t{1}\t{2}", o.Key, o.Size, o.LastModified);
}
but I would like to unzip these files on the fly to a specific location instead of copy them locally.
I tried the following but it did not work
using (ZipArchive archive = ZipFile.OpenRead(responses.ResponseStream.ToString())) //unzip file
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
archive.ExtractToDirectory(myPath);
}
}
}
Thanks
ZipFile.OpenRead() takes a file name of a local file so that won't work. You can, however, unzip an archive in a MemoryStream (see this answer and this answer).
I am trying to zip a folder using IonicZip library in C#. It is able to zip .txt, .exe, .pdf etc. in the folder, but not able to zip folder in folder.
It is able to zip MusicLogs.txt and Video.exe but cannot Music folder.Music folder contains some folder also. It doesnt see Music folder even while debugging. My code is :
string zipPath = #"C:\" + DateTime.Now.ToString("yyyy-MM-dd HH-mm") + ".zip"; // zipped file extracts here
string filename = #"E:\"; // the fodler which should be zipped. File must be exist
using (ZipFile zipFile = new ZipFile())
{
zipFile.Password = "asd";
zipFile.Encryption = EncryptionAlgorithm.PkzipWeak;
foreach (string file in Directory.GetFiles(filename)) // this foreach is for getting all files in a folder.
{
zipFile.AddFile(file, "YESMusic"); // set file
}
zipFile.Save(zipPath);
}
Where is the problem ? Need a change in AddFile function ? Thanks
This will work:
using (ZipFile zipFile = new ZipFile())
{
zipFile.Password = "asd";
zipFile.Encryption = EncryptionAlgorithm.PkzipWeak;
// Adding folders in the base directory
foreach (var item in Directory.GetDirectories(filename))
{
string folderName = new DirectoryInfo(item).Name;
zipFile.AddDirectory(item, folderName);
}
// Adding files in the base directory
foreach (string file in Directory.GetFiles(filename))
{
zipFile.AddFile(file);
}
zipFile.Save(zipPath);
}
I have some code that adds different directories to a zip file. Its important that I know each folder based on its comment, during the extraction process. Here is the zip sample code:
foreach (string folder in BackupDIRS)
{
string Source = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), folder);
string Folder = Path.GetFileName(Path.GetDirectoryName(Source));
ZipEntry e = zip.AddDirectory(Source, Folder);
e.Comment = "comment here";
}
Here is the code for unzipping:
using (ZipFile zip1 = ZipFile.Read(src))
{
foreach (ZipEntry e in zip1.Entries)
{
// e.comment will be null on actual files.
}
}
The actual entry points for the folder have comments but their files dont, which presents a problem since it will cause most entries to have null comments.
How do I make the files have the same comment as the folder, or does DotNetZip extract directory files sequentially, meaning if its null I could use the last non null value because it would be that folder's files.
After calling ZipEntry e = zip.AddDirectory(Source, Folder); you can iterate through all files in ZipEntry and assign a comment:
using (var zipFile = new ZipFile(zipFilePath))
{
var addDirectory = zipFile.AddDirectory(directoryPathToAdd, "directory");
addDirectory.Comment = "directory comment";
var zipEntries = zipFile.Entries
.Where(x => !x.IsDirectory)
.Where(x => x.FileName.StartsWith("directory"));
foreach (var zipentry in zipEntries)
zipentry.Comment = "zip entry comment";
zipFile.Save();
}
Hope it helps.