DotNetZip trouble with russian encoding - c#

i use DotNetZip in my project.
using (var zip = new ZipFile())
{
zip.ProvisionalAlternateEncoding = System.Text.Encoding.GetEncoding(866);
zip.AddFile(filename, "directory\\in\\archive");
zip.Save("archive.zip");
}
all ok but when i use method AddDirectoryByName i have a bad directory names.

Universal way for all is :
zip.AlternateEncoding = Encoding.UTF8;
zip.ProvisionalAlternateEncoding = Encoding.GetEncoding(Console.OutputEncoding.CodePage);
zip.AlternateEncodingUsage = ZipOption.AsNecessary;

This way in new version work for me
zip.AlternateEncodingUsage = ZipOption.Always;
zip.AlternateEncoding = Encoding.GetEncoding(866);

You may Peek Definition first.
Then you will find this:
public ZipFile(Encoding encoding);
So you can use this:
using (ZipFile zip = new ZipFile(Encoding.UTF8))

Related

Can't seem to zip up xml file correctly using C#

Ok so I have tried numerous examples on the web, but I can't seem to get any working.
I have the following code which creates a zip archive, and when I extract the zip archive there is a xml file.
string filePathZip = Path.Combine(HttpRuntime.AppDomainAppPath, "content\\files\\exportimport",
prependStoreId + "ebayproductinventorysyncfeed.zip");
using (FileStream zipToOpen = new FileStream(filePathZip, (!File.Exists(filePathZip)) ? FileMode.CreateNew : FileMode.Open))
{
using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Update))
{
//byte[] bytes = File.ReadAllBytes(oldFilePath);
ZipArchiveEntry readmeEntry = archive.CreateEntry(oldFilePath);
using (StreamWriter writer = new StreamWriter(readmeEntry.Open()))
{
writer.Write(oldFilePath);
Debug.WriteLine("Information about this package.");
Debug.WriteLine("========================");
}
}
}
Now the problem is if I open that xml file the data from the original xml file is not there. So instead of seeing something like this:
<?xml version="1.0" encoding="utf-8"?>
<ReviseInventoryStatusRequest xmlns="urn:ebay:apis:eBLBaseComponents">
<RequesterCredentials>
<eBayAuthToken></eBayAuthToken>
</RequesterCredentials>
<Version>967</Version>
<ErrorLanguage>en_US</ErrorLanguage>
<WarningLevel>High</WarningLevel>
</ReviseInventoryStatusRequest>
I get this:
C:\projects\website\Presentation\Nop.Web\content\files\exportimport\ebaylmsinventoryfeed.xml
I figure it's something to do with opening the file as a stream, just can't figure it out as I'm fairly new to C#.
I have also tried:
writer.Write(bytes);
Can anyone help, cheers.
I get this:
C:\projects\website\Presentation\Nop.Web\content\files\exportimport\ebaylmsinventoryfeed.xml
That's what you told it to do:
writer.Write(oldFilePath);
Perhaps instead:
using (var dest = readmeEntry.Open()))
using (var source = File.OpenRead(oldFilePath))
{
source.CopyTo(dest);
}

Compressing a folder to gzip/zip file from PCL

I am developing UWP and Windows phone 8.1 in the same solution.
On both projects I need a functionality of compressing a whole folder to one gzip file (in order to send it to server).
Libraries I've tried and encountered issues with:
SharpZipLib - uses System.IClonable which I cannot referance in my PCL project
DotNetZip - Not Suporting PCL/UWP
System.IO.Compression - Work only with Stream, cannot compress whole folder
I can split the implementation for each platform (although it is not perfect) but I still didn't found something that can be used in UWP.
Any help will be appriciated
Ok, so I found this project called SharpZipLib.Portable which is also an open source
Github : https://github.com/ygrenier/SharpZipLib.Portable
Really nice :)
Working on a UWP library you will have to use the Stream subsystem of the System.IO.Compression. There are many such limitations when you need a PCL version of .NET Framework. Live with that.
In your context that is not much of a trouble.
The required usings are:
using System;
using System.IO;
using System.IO.Compression;
Then the methods...
private void CreateArchive(string iArchiveRoot)
{
using (MemoryStream outputStream = new MemoryStream())
{
using (ZipArchive archive = new ZipArchive(outputStream, ZipArchiveMode.Create, true))
{
//Pick all the files you need in the archive.
string[] files = Directory.GetFiles(iArchiveRoot, "*", SearchOption.AllDirectories);
foreach (string filePath in files)
{
FileAppend(iArchiveRoot, filePath, archive);
}
}
}
}
private void FileAppend(
string iArchiveRootPath,
string iFileAbsolutePath,
ZipArchive iArchive)
{
//Has to return something like "dir1/dir2/part1.txt".
string fileRelativePath = MakeRelativePath(iFileAbsolutePath, iArchiveRootPath);
ZipArchiveEntry clsEntry = iArchive.CreateEntry(fileRelativePath, CompressionLevel.Optimal);
Stream entryData = clsEntry.Open();
//Write the file data to the ZipArchiveEntry.
entryData.Write(...);
}
//http://stackoverflow.com/questions/275689/how-to-get-relative-path-from-absolute-path
private string MakeRelativePath(
string fromPath,
string toPath)
{
if (String.IsNullOrEmpty(fromPath)) throw new ArgumentNullException("fromPath");
if (String.IsNullOrEmpty(toPath)) throw new ArgumentNullException("toPath");
Uri fromUri = new Uri(fromPath);
Uri toUri = new Uri(toPath);
if (fromUri.Scheme != toUri.Scheme) { return toPath; } // path can't be made relative.
Uri relativeUri = fromUri.MakeRelativeUri(toUri);
String relativePath = Uri.UnescapeDataString(relativeUri.ToString());
if (toUri.Scheme.Equals("file", StringComparison.OrdinalIgnoreCase))
{
relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
}
return relativePath;
}

Extract file from LZH archive

I have LZH archive (.lzh, .lha extensions of archive), and need to extract file from it in .NET Framework 4? Does .NET Framework 4 have some built in toolset for this?
I ported an LHA Java decompression library to .NET called LHA Decompressor.
Thanks very much to the author above. I have posted a simple implementation of it for reference.
//Extracts all files in the .lzh archive
LhaFile lhaFile = null;
byte[] dest = new byte[8];
List<string> extractedFileList = new List<string>();
lhaFile = new LhaFile(filePath, Encoding.UTF7);
IEnumerator<LhaEntry> enumerator = lhaFile.GetEnumerator();
while (enumerator.MoveNext())
{
string fileName = enumerator.Current.GetPath();
LhaEntry lhaEntry = lhaFile.GetEntry(fileName);
dest = lhaFile.GetEntryBytes(lhaEntry);
File.WriteAllBytes(Path.Combine(extractionPath, fileName), dest);
string fullPath = Path.Combine(extractionPath, fileName);
extractedFileList.Add(fullPath);
}
lhaFile.Close();

How do I get ZipArchive.CreateEntry name encoding right?

I use the following code to create a zip archive with C#.
using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Create, false))
{
var zipEntry = zipArchive.CreateEntry(name + ".pdf");
...
}
The name often consist of Swedish characters such as ÅÄÖ åäö. When I open the zip and look at the names the Swedish chars are garbled like this "Fl+Âdesm+ñtare.pdf".
I tried fixing the name encoding with this code. But it didn't work.
var iso = Encoding.GetEncoding("ISO-8859-1");
var utf8 = Encoding.UTF8;
var utfBytes = utf8.GetBytes(name);
var isoBytes = Encoding.Convert(utf8, iso, utfBytes);
var isoName = iso.GetString(isoBytes);
Any ideas?
Since DotNetZip is a dead project and this article is relevant to google searches, here is an alternative solution with the IO.Compression library :
Archive = New IO.Compression.ZipArchive(Stream, ZipArchiveMode, LeaveOpen, Text.Encoding.GetEncoding(Globalization.CultureInfo.CurrentCulture.TextInfo.OEMCodePage))
This might not cover all conversions, from what I gathered from the sources on the subject, the underlying code uses the local machine's (server) regional culture's encoding page for entry names. Mapping them with that encoding explicitly has fixed the issue for my client-domain, no guarantees that it's a silver bullet however.
You can try out DotNetZip library (get it via NuGet). Here is a code sample, where i use cp866 encoding:
private string GenerateZipFile(string filename, BetPool betPool)
{
using (var zip = new ZipFile(Encoding.GetEncoding("cp866")))
{
//zip.Password = AppConfigHelper.Key + DateTime.Now.Date.ToString("ddMMyy");
zip.AlternateEncoding = Encoding.GetEncoding("cp866");
zip.AlternateEncodingUsage = ZipOption.AsNecessary;
zip.AddFile(filename, "");
var zipFilename = FormZipFileName(betPool);
zip.Save(zipFilename);
return zipFilename;
}
}
using (var zip = new ZipArchive(ZipFilePath, ZipArchiveMode.Read, false, Encoding.GetEncoding("cp866")))

Rename File in IsolatedStorage

I need to rename a file in the IsolatedStorage. How can I do that?
There doesn't appear to anyway in native C# to do it (there might be in native Win32, but I don't know).
What you could do is open the existing file and copy it to a new file and delete the old one. It would be slow compared to a move, but it might be only way.
var oldName = "file.old"; var newName = "file.new";
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
using (var readStream = new IsolatedStorageFileStream(oldName, FileMode.Open, store))
using (var writeStream = new IsolatedStorageFileStream(newName, FileMode.Create, store))
using (var reader = new StreamReader(readStream))
using (var writer = new StreamWriter(writeStream))
{
writer.Write(reader.ReadToEnd());
}
In addition to the copy to a new file, then delete the old file method, starting with Silverlight 4 and .NET Framework v4, IsolatedStorageFile exposes MoveFile and MoveDirectory methods.
Perfectly execute this piece of code
string oldName="oldName";
string newName="newName";
var file = await ApplicationData.Current.LocalFolder.GetFileAsync(oldName);
await file.RenameAsync(newName);

Categories