I have a zip password file and know this password.
I need open this zip file in Windows 8 metro app program code.
But 'System.IO.Compression.ZipArchive' is not supported decompress zip with password in Windows 8 metro app program code.
I'm try SharpZipLib and DotNetZip. BUT they are not support net 4.5. So i doesn't use them in my metro program code.
I'm try Ionic.Zip. It's ok in program code. I want to build packages to upload to the windows store. But not pass in microsoft code review.
Is there another way?
thanks a lot
The System.IO.Compression.FileSystem assembly is not available for Windows Store apps, so you cannot use the ExtractToDirectory extension method of the ZipFileExtensions class.
Instead of DirectoryInfo, FileInfo, etc. use StorageFile. See Accessing data and files and the File access sample for more information on how to read and write files in Metro style apps. Then you'll need to read the data from the file into a stream and then pass that to methods of one of the following class (your choice):
DeflateStream (which internally uses zlib as of .NET 4.5)
ZipArchive or GZipStream classes. Those are available to Metro style apps, even if the file specific extension methods are not.
Windows Runtime type Decompressor to decompress files.
you can using https://sharpcompress.codeplex.com/.
it support open file zip have password
code bellow
//if file zip have a file pdf , a file xml
async void Read(StorageFile file)
{
MemoryStream memoryFilePDf = new MemoryStream();
MemoryStream memoryFileXml = new MemoryStream();
FilePdf = null;
FileXml = null;
using (var zipStream = await file.OpenStreamForReadAsync())
{
using (MemoryStream zipMemoryStream = new MemoryStream((int)zipStream.Length))
{
await zipStream.CopyToAsync(zipMemoryStream);
try
{
using (var archive = ZipArchive.Open(zipMemoryStream, PassWord))
{
bool isFilePdf = false;
foreach (var entry in archive.Entries)
{
if (!entry.Key.ToLower().EndsWith(".pdf") && !entry.Key.ToLower().EndsWith(".xml"))
{
continue;
}
if (entry.Key.ToLower().EndsWith(".pdf"))
{
isFilePdf = true;
entry.WriteTo(memoryFilePDf);
}
else
{
isFilePdf = false;
entry.WriteTo(memoryFileXml);
}
var fileName = entry.Key.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries).LastOrDefault();
var createFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(fileName, Windows.Storage.CreationCollisionOption.GenerateUniqueName);
using (IRandomAccessStream stream = await createFile.OpenAsync(FileAccessMode.ReadWrite))
{
// Write compressed data from memory to file
using (Stream outstream = stream.AsStreamForWrite())
{
byte[] buffer = isFilePdf ? memoryFilePDf.ToArray() : memoryFileXml.ToArray();
outstream.Write(buffer, 0, buffer.Length);
outstream.Flush();
}
}
if (isFilePdf)
{
FilePdf = createFile;
}
else
{
FileXml = createFile;
}
}
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
}
Related
I have been researching this topic for days and I can't find anything on managing files on a MTP Portable Device (More specifically a Galaxy S4).
I want to be able to...
Copy files from the PC to the MTP Device
Copy files from the MTP Device to the PC
Delete files from the MTP Device
I really want to copy MP3 files but if there is a general way to copy over and file supported by MTP that would be awesome. I've looked into the Window Portable Device API but I couldn't find anywhere where there is sample code in C#.
Any blogs, sample code, and files would be very helpful. Thanks! :)
I used a nugetpackage called MediaDevices
this made it very easy for me to copy my photos from my android phone to my computer.
public class Program
{
static void Main(string[] args)
{
var devices = MediaDevice.GetDevices();
using (var device = devices.First(d => d.FriendlyName == "Galaxy Note8"))
{
device.Connect();
var photoDir = device.GetDirectoryInfo(#"\Phone\DCIM\Camera");
var files = photoDir.EnumerateFiles("*.*", SearchOption.AllDirectories);
foreach (var file in files)
{
MemoryStream memoryStream = new System.IO.MemoryStream();
device.DownloadFile(file.FullName, memoryStream);
memoryStream.Position = 0;
WriteSreamToDisk($#"D:\PHOTOS\{file.Name}", memoryStream);
}
device.Disconnect();
}
}
static void WriteSreamToDisk(string filePath, MemoryStream memoryStream)
{
using (FileStream file = new FileStream(filePath, FileMode.Create, System.IO.FileAccess.Write))
{
byte[] bytes = new byte[memoryStream.Length];
memoryStream.Read(bytes, 0, (int)memoryStream.Length);
file.Write(bytes, 0, bytes.Length);
memoryStream.Close();
}
}
}
There is also a nuget package called WPDApi which worked well for me, after I managed to download the source code (had problems with nuget):
https://github.com/Duke-fleed/WPDApi
I am trying to use SharpZip.unzipper for my windows phone 8.1. However it is not reading some of the code. Since i am fairly new to windows phone development please let me know the alternatives of following code for WP8.1
using System.Windows.Resources;
public Stream GetFileStream(string filename)
{
if (fileEntries == null)
fileEntries = ParseCentralDirectory(); //We need to do this in case the zip is in a format Silverligth doesn't like
long position = this.stream.Position;
this.stream.Seek(0, SeekOrigin.Begin);
Uri fileUri = new Uri(filename, UriKind.Relative);
StreamResourceInfo info = new StreamResourceInfo(this.stream, null);
StreamResourceInfo stream = System.Windows.Application.GetResourceStream(info, fileUri);
this.stream.Position = position;
if (stream != null)
return stream.Stream;
return null;
}
Windows.Resources seems missing
I can't call StreamResourceInfo, System.Windows.Application
I have tried using App. but there is no function for GetResourceSteam
I am not sure what to do here
There are quite a few differences between WP8.1 runtime and WP8.1 Silverlight.
The code sample that you have will run on WP8.0 SL and WP8.1 SL.
It looks like you created a Windows Phone 8.1 runtime project. There is no System.Windows.Application.GetResourceStream()
Either convert it to a compatible 8.1 runtime stream or recreate your project to target Silverlight instead.
// sample
private async void ZipLibraryTest()
{
// create the full path
string zip = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "filename.zip");
// create the storage file with the file name
StorageFile sf = await StorageFile.GetFileFromPathAsync(zip);
// create the IO Stream
using (System.IO.Stream output = await sf.OpenStreamForWriteAsync())
{
// open the zip file for writing, use the stream from the file
ZipFile zf = ZipFile.Create(output);
// rest of your code
// ...
// ...
// close the zip file
zf.Close();
}
}
When I connect my Android phone to my Windows 7 with USB cable, Windows pop-up a window and show me the phone's internal storage at Computer\HTC VLE_U\Internal storage from Windows Explorer. But there is no drive letter linked with this phone storage! Inside Windows Explorer, I can manipulate the file system.
How can I manipulate the same files or folders from C# program?
As I tested,
DirectoryInfo di = new DirectoryInfo(#"C:\");
works, but
DirectoryInfo di = new DirectoryInfo(#"Computer\HTC VLE_U\Internal storage");
failed.
But in Windows Explorer, IT IS Computer\HTC VLE_U\Internal storage! No drive letter!
Yes, this is MTP device.
I see this answer in Stack Overflow, but the return results are empty for me after running this code
var drives = DriveInfo.GetDrives();
var removableFatDrives = drives.Where(
c=>c.DriveType == DriveType.Removable &&
c.DriveFormat == "FAT" &&
c.IsReady);
var androids = from c in removableFatDrives
from d in c.RootDirectory.EnumerateDirectories()
where d.Name.Contains("android")
select c;
I get correct drives. But android phone's internal storage is not here.
Both removableFatDrives and androids are empty for me.
I used nugetpackage "Media Devices by Ralf Beckers v1.8.0"
This made it easy for me to copy my photos from my device to my computer and vice versa.
public class Program
{
static void Main(string[] args)
{
var devices = MediaDevice.GetDevices();
using (var device = devices.First(d => d.FriendlyName == "Galaxy Note8"))
{
device.Connect();
var photoDir = device.GetDirectoryInfo(#"\Phone\DCIM\Camera");
var files = photoDir.EnumerateFiles("*.*", SearchOption.AllDirectories);
foreach (var file in files)
{
MemoryStream memoryStream = new System.IO.MemoryStream();
device.DownloadFile(file.FullName, memoryStream);
memoryStream.Position = 0;
WriteSreamToDisk($#"D:\PHOTOS\{file.Name}", memoryStream);
}
device.Disconnect();
}
}
static void WriteSreamToDisk(string filePath, MemoryStream memoryStream)
{
using (FileStream file = new FileStream(filePath, FileMode.Create, System.IO.FileAccess.Write))
{
byte[] bytes = new byte[memoryStream.Length];
memoryStream.Read(bytes, 0, (int)memoryStream.Length);
file.Write(bytes, 0, bytes.Length);
memoryStream.Close();
}
}
}
Using ZackOfAllTrades' code, I ran into OutOfMemoryException when invoking MediaDevice.DownloadFile(string, Stream).
[1] Go to project properties, set project to build for x64, that seems to get rid of OutOfMemoryException; I am able to start copying files between 1GB to 2GB without any problems.
[2] However, as soon as I start copying files of 2.5GB the WriteStreamToDisk() util function by ZackOfAllTrades started to complain about Stream too long.
DownloadFile takes a Stream object, it doesn't need to be a MemoryStream so I switched it to a FileStream object :
static void Main(string[] args)
{
string DeviceNameAsSeenInMyComputer = "Mi Note 10 Pro";
var devices = MediaDevice.GetDevices();
using (var device = devices.Where(d => d.FriendlyName == DeviceNameAsSeenInMyComputer || d.Description == DeviceNameAsSeenInMyComputer).First())
{
device.Connect();
var photoDir = device.GetDirectoryInfo(#"\Internal shared storage\DCIM\Camera");
var files = photoDir.EnumerateFiles("*.*", SearchOption.TopDirectoryOnly);
foreach (var file in files)
{
string destinationFileName = $#"F:\Photo\{file.Name}";
if (!File.Exists(destinationFileName))
{
using (FileStream fs = new FileStream(destinationFileName, FileMode.Create, System.IO.FileAccess.Write))
{
device.DownloadFile(file.FullName, fs);
}
}
}
device.Disconnect();
}
Console.WriteLine("Done...");
Console.ReadLine();
}
Worked beautifully. When I am using ZackOfAllTrades' code, VS profiler shows memory consumption at about 2.5 times the size of file.
Eg: if the file is 1.5GB large, the memory consumption is roughly 4GB. But if one is to copy to file system directly, the memory consumption is negligible (<50mb).
The other issue is with MediaDevice.FriendlyName. I know for sure my Xiaomi Note 10 Pro did not support FriendlyName. What worked for me is MediaDevice.Description.
i have problems during parsing request files.
my file size is 1338521 bytes, but Nancy says, that file size is some times 1751049 or 3200349.
on my windows pc it works fine, on linux server this problem appears, so i can't save file.
string result = Convert.ToBase64String(Core.ReadBytesFromStream(file.Value));
using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(result)))
{
using (Bitmap bm2 = new Bitmap(ms))
{
bm2.Save(path);
}
}
any ideas?
You don't need to convert the file like that.
var filename = Path.Combine(storagePath, Request.Files[0].Name);
using (var fileStream = new FileStream(filename, FileMode.Create))
{
Request.Files[0].Value.CopyTo(fileStream);
}
Validate the file when it comes in to ensure the extension is accepted, create a save path, and copy the stream to a new file on the filesystem.
That's it.
Does anyone know of a good way to compress or decompress files and folders in C# quickly? Handling large files might be necessary.
The .Net 2.0 framework namespace System.IO.Compression supports GZip and Deflate algorithms. Here are two methods that compress and decompress a byte stream which you can get from your file object. You can substitute GZipStream for DefaultStream in the methods below to use that algorithm. This still leaves the problem of handling files compressed with different algorithms though.
public static byte[] Compress(byte[] data)
{
MemoryStream output = new MemoryStream();
GZipStream gzip = new GZipStream(output, CompressionMode.Compress, true);
gzip.Write(data, 0, data.Length);
gzip.Close();
return output.ToArray();
}
public static byte[] Decompress(byte[] data)
{
MemoryStream input = new MemoryStream();
input.Write(data, 0, data.Length);
input.Position = 0;
GZipStream gzip = new GZipStream(input, CompressionMode.Decompress, true);
MemoryStream output = new MemoryStream();
byte[] buff = new byte[64];
int read = -1;
read = gzip.Read(buff, 0, buff.Length);
while (read > 0)
{
output.Write(buff, 0, read);
read = gzip.Read(buff, 0, buff.Length);
}
gzip.Close();
return output.ToArray();
}
I've always used the SharpZip Library.
Here's a link
You can use a 3rd-party library such as SharpZip as Tom pointed out.
Another way (without going 3rd-party) is to use the Windows Shell API. You'll need to set a reference to the Microsoft Shell Controls and Automation COM library in your C# project. Gerald Gibson has an example at:
Internet Archive's copy of the dead page
As of .Net 1.1 the only available method is reaching into the java libraries.
Using the Zip Classes in the J# Class Libraries to Compress Files and Data with C#
Not sure if this has changed in recent versions.
My answer would be close your eyes and opt for DotNetZip. It's been tested by a large community.
GZipStream is a really good utility to use.
This is very easy to do in java, and as stated above you can reach into the java.util.zip libraries from C#. For references see:
java.util.zip javadocs
sample code
I used this a while ago to do a deep (recursive) zip of a folder structure, but I don't think I ever used the unzipping. If I'm so motivated I may pull that code out and edit it into here later.
Another good alternative is also DotNetZip.
You can create zip file with this method:
public async Task<string> CreateZipFile(string sourceDirectoryPath, string name)
{
var path = HostingEnvironment.MapPath(TempPath) + name;
await Task.Run(() =>
{
if (File.Exists(path)) File.Delete(path);
ZipFile.CreateFromDirectory(sourceDirectoryPath, path);
});
return path;
}
and then you can unzip zip file with this methods:
1- This method work with zip file path
public async Task ExtractZipFile(string filePath, string destinationDirectoryName)
{
await Task.Run(() =>
{
var archive = ZipFile.Open(filePath, ZipArchiveMode.Read);
foreach (var entry in archive.Entries)
{
entry.ExtractToFile(Path.Combine(destinationDirectoryName, entry.FullName), true);
}
archive.Dispose();
});
}
2- This method work with zip file stream
public async Task ExtractZipFile(Stream zipFile, string destinationDirectoryName)
{
string filePath = HostingEnvironment.MapPath(TempPath) + Utility.GetRandomNumber(1, int.MaxValue);
using (FileStream output = new FileStream(filePath, FileMode.Create))
{
await zipFile.CopyToAsync(output);
}
await Task.Run(() => ZipFile.ExtractToDirectory(filePath, destinationDirectoryName));
await Task.Run(() => File.Delete(filePath));
}