Invalid filename retrieved from zip file C# - c#

Hi I'm trying to read a zip file which contains multiple files. Few of the files inside is named in Arabic.
My file name: (Final تدريب.pdf) becomes (Final óº⌐∩á.pdf) instead. I hope you can guide me.
Here is my code:
using Ionic.Zip;
using (ZipFile zip = ZipFile.Read(path))
{
foreach (var entry in zip.Entries)
{
string name = entry.FileName;
}
}

Related

Can I maintain directory structure when zipping file?

I'm attempting to zip up a handful of files but these files could exist in different directories. The zipping portion is working correctly but I cannot figure out how to get it to preserve the directory structure within the zip file.
Here's what I have so far:
public static void CreateZipFile(IEnumerable<FileInfo> files, string archiveName)
{
using (var stream = File.OpenWrite(archiveName))
using (var archive = new ZipArchive(stream, ZipArchiveMode.Create))
{
foreach (var item in files)
{
archive.CreateEntryFromFile(item.FullName, item.Name, CompressionLevel.Optimal);
}
}
}
Is this possible?
#ErocM the link provided by #Flydog57 gives you exactly what you want. You are not exploiting the entryName argument correctly (the second argument in your case when calling CreateEntryFromFile).
Independently of which file you are adding to the archive (from same of different folders), you have to structure your archive using the entryName argument the C# api gives to you.
If your file's fullname is /tmp/myfile.txt, and you do archive.CreateEntryFromFile(item.FullName, item.Name), then the archive entry name will be myfile.txt. No folder created as the entry name doesn't contain folder structure in it's name.
However, if you call archive.CreateEntryFromFile(item.FullName, item.FullName), you will then have you file folder structure into the archive.
You can try with your function just changing item.Name into item.FullName.
Just be careful, on windows; if you path is C:\tmp\myfile.txt for instance, the archive will not be extractable correctly. You can then add some little code to remove C: from the full name of your files.
Some examples taking your implementation:
using System;
using System.IO;
using System.Collections.Generic;
using System.IO.Compression;
namespace ConsoleApp
{
internal class Program
{
static void Main(string[] args)
{
FileInfo f1 = new FileInfo(#"/tmp/test1.txt");
FileInfo f2 = new FileInfo(#"/tmp/testdir/test2.txt");
List<FileInfo> files = new();
files.Add(f1);
files.Add(f2);
CreateZipFile(files, #"/tmp/archive.zip");
}
public static void CreateZipFile(IEnumerable<FileInfo> files, string archiveName)
{
using (var stream = File.OpenWrite(archiveName))
using (var archive = new ZipArchive(stream, ZipArchiveMode.Create))
{
foreach (var item in files)
{
// Here for instance, I put all files in the input list in the same directory, without checking from where they are in the host file system.
archive.CreateEntryFromFile(item.FullName, $"mydir/{item.Name}", CompressionLevel.Optimal);
// Here, I am just using the actual full path of the file. Be careful on windows with the disk name prefix (C:, D:, etc...).
// archive.CreateEntryFromFile(item.FullName, item.FullName, CompressionLevel.Optimal);
}
}
}
}

How to Detect a Compressed File in C#

I'm trying to write a text search routine that scans a directory for a given wildcard file spec and scans the matches for a given search string. Everything works except for when I get to ZIP files. Here's the relevant code:
string fileText = File.ReadAllText(filePath);
foreach (string s in lstSearchStrings.Items)
{
int cnt = CountSubStrings(fileText, s);
lstCounts.Items.Add(cnt.ToString());
}
I know it only uses text-based routines so I probably need to change that. Any help in where to make changes / what to do would be appreciated!
You can use SharpZipLib to read inside zip files.
using ICSharpCode.SharpZipLib.Zip;
using (var zipFile = new ZipFile(#"test.zip"))
{
foreach (ZipEntry entry in zipFile)
{
Console.WriteLine(entry.Name);
}
}
First you detect zip files using extension. Then read those using above method.
string fileText = File.ReadAllText(entry.name);

How to Extract ZIP file from specific path inside ZIP C# Ionic

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.

Extracting files nested within a zip file using System.IO.Compression C#

I have a number of zip files that contain .txt files nested in sub directories within the zip file. I am trying to extract the .txt files and output them to another directory, however I am getting an error 'Could not find a part of the path...' This error occurs at the 'entry.FullName' point
I believe I need to remove the file path at some stage of the unzip process since I can get the code to run if I use zip files with .txt files in them without any sub-directories. Any pointers would be much appreciated.
Here is my code:
class Program
{
static void Main(string[] args)
{
DateTime dt = DateTime.Now;
foreach (var zp in Directory.GetFiles(#"D:\\My Documents\\DMU\\Frontrunner2015\\ZipIn\\", "*.zip"))
{
string zipPath = zp;
string extractPath = #"D:\\My Documents\\DMU\\Frontrunner2015\\ZipOut\\";
using (ZipArchive archive = ZipFile.OpenRead(zipPath))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (entry.FullName.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
{
entry.ExtractToFile(Path.Combine(extractPath, entry.FullName));
}
foreach (var file in Directory.GetFiles(extractPath))
{.....
Would have helped if you left the path in the error message there so people could see what path was not found. I would guess that when you combine extractPath and FullName you end up with a folder name that does not exist - as you mentioned the files in the zip file have subdirectories.
I think you really meant to use Name property in your Path.Combine call.

Packing files and folders into a single file

I'm tring to create a program to archieve some files from a folder to a single binary file so I can read files from the binary archieve later.
So I created a archivation method but I don't really know how can I read the files from the binary without unpacking them...
Some code:
public static void PackFiles()
{
using (var doFile = File.Create("root.extension"))
using (var doBinary = new BinaryWriter(doFile))
{
foreach (var file in Directory.GetFiles("Data"))
{
doBinary.Write(true);
doBinary.Write(Path.GetFileName(file));
var data = File.ReadAllBytes(file);
doBinary.Write(data.Length);
doBinary.Write(data);
}
doBinary.Write(false);
}
}
Also, can I set a kind of "password" to the binary file so the archieve can only be unpacked if the password is known?
P.S: I dont need zip :)
I think the best way to go is using ZIP for this.
There is a solid and fast library called dotnetzip
Example using password:
using (ZipFile zip = new ZipFile())
{
zip.Password= "123456!";
zip.AddFile("ReadMe.txt");
zip.AddFile("7440-N49th.png");
zip.AddFile("2005_Annual_Report.pdf");
zip.Save("Backup.zip");
}

Categories

Resources