I have a problem when opening a zip file. I am using this code to zip the file:
public static string Zip_File(string soruce , string target)
{
try
{
byte[] bufferWrite;
using (FileStream fsSource = new FileStream(soruce, FileMode.Open, FileAccess.Read, FileShare.Read))
{
bufferWrite = new byte[fsSource.Length];
fsSource.Read(bufferWrite, 0, bufferWrite.Length);
using (FileStream fsDest = new FileStream(target, FileMode.OpenOrCreate, FileAccess.Write))
{
using (GZipStream gzCompressed = new GZipStream(fsDest, CompressionMode.Compress, true))
{
gzCompressed.Write(bufferWrite, 0, bufferWrite.Length);
bufferWrite = null;
fsSource.Close();
gzCompressed.Close();
fsDest.Close();
}
}
}
return "success";
}
catch (Exception ex)
{
return ex.Message;
}
}
When I call this function, I am receiving "success" message, but I can't open the zip file. This is my function call code:
ZipFiles.Zip_File(#"C:\Documents and Settings\ccspl\Desktop\IntegrityDVR.mdb", #"C:\Documents and Settings\ccspl\Desktop\a.zip")
This is the error message I receive:
the compressed(folder) is invalid or corrupted
GZipStream does not create .zip files. It creates .gz files. If you need to create .zip files, you should use something like SharpZipLib.
but, wait a minute, GZipStream doesn't create zip file, it creates gzip files as I know, Zipping files using GZipStream should help
Why not use SharpZipLib? It makes this a lot easier.
sample code for DotNetZip, an open source zip library.
public static string ZipFile(String source, String target)
{
try
{
using (ZipFile zip = new ZipFile()
{
zip.AddFile(source);
zip.Save(target);
}
return "success";
}
catch {}
return "failure";
}
Related
I'm making a program that reads file after I select a file and write file in hex. Problem is BinaryReader still open after .Close(); and it gives me System.IO.IOException: the process cannot access the file error when i try to write a file. I'm missing something?
Here is the code that read the file after i select file from dialogbox..
BinaryReader br = new BinaryReader(File.OpenRead(sfile.FileName));
string pted = null;
br.BaseStream.Position = 0x12;
pted += br.ReadByte().ToString("X2");
if (pted == "01")
{
}
else
{
}
br.Close();
And here is the code that writes file when you click a button
Stream st = File.Open(pathTextBox.Text, FileMode.Open);
st.Seek(0x12, SeekOrigin.Begin);
st.WriteByte(0x00);
st.Close();
add br.close in a try catch statement and dispose the binary reader after closing
for example:
try{
br.close();
br.dispose();
}
catch(Exception exp)
{
//Assuming you have included using 'namespace System.Diagnostics'
Debug.WriteLine(exp.ToString());
}
You can read more on BinaryReader here
First check if file is here, then try it with using directive.
As mentioned by Orgen:
if(File.Exists(#pathTextBox.Text)
{
using(Stream st = File.Open(pathTextBox.Text, FileMode.Open))
{
st.Seek(0x12, SeekOrigin.Begin);
st.WriteByte(0x00);
}
}
the using() will take care of the disposable.
I have a JSON file created, and I am going to zip it using DotNetZip.
Using with StreamWriter to zip it is working, if I try to use MemoryStream it will not working.
StreamWriter :
sw = new StreamWriter(assetsFolder + #"manifest.json");
sw.Write(strManifest);
sw.Close();
zip.AddFile(Path.Combine(assetsFolder, "manifest.json"), "/");
zip.AddFile(Path.Combine(assetsFolder, "XXXXXXX"), "/");
zip.Save(outputStream);
MemoryStream :
var manifestStream = GenerateStreamFromString(strManifest);
public static Stream GenerateStreamFromString(string s)
{
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
return stream;
}
zip.AddEntry("manifest.json", manifestStream);
zip.AddFile(Path.Combine(assetsFolder, "XXXXXXX"), "/");
zip.Save(outputStream);
I must using the .JSON file type to zip it, Can any one told me where have a mistake?
To create a Gzipped Json you need to use GZipStream. Try method below.
https://www.dotnetperls.com/gzipstream
GZipStream compresses data. It saves data efficiently—such as in
compressed log files. We develop a utility method in the C# language
that uses the System.IO.Compression namespace. It creates GZIP files.
It writes them to the disk.
public static void CompressStringToFile(string fileName, string value)
{
// A.
// Write string to temporary file.
string temp = Path.GetTempFileName();
File.WriteAllText(temp, value);
// B.
// Read file into byte array buffer.
byte[] b;
using (FileStream f = new FileStream(temp, FileMode.Open))
{
b = new byte[f.Length];
f.Read(b, 0, (int)f.Length);
}
// C.
// Use GZipStream to write compressed bytes to target file.
using (FileStream f2 = new FileStream(fileName, FileMode.Create))
using (GZipStream gz = new GZipStream(f2, CompressionMode.Compress, false))
{
gz.Write(b, 0, b.Length);
}
}
I have a problem with a zip-file created with the old PKZIP® Command Line for Windows version 4 from the year 2000.
I am using ICSharpCode.SharpZipLib to extract the file.
Windows has no problem to open the file in the Explorer.
Here is the code:
private void Extract(string zipFile, string outputfolder)
{
try
{
_logger.InfoFormat("Extracting {0}", zipFile);
System.IO.Stream stream = new System.IO.FileStream(zipFile, System.IO.FileMode.Open);
ZipInputStream zipInputStream = new ZipInputStream(stream);
ZipEntry zipEntry = zipInputStream.GetNextEntry(); //Throws Compression error exception
while (zipEntry != null)
{
String entryFileName = zipEntry.Name;
_logger.InfoFormat("Entry-Filename: {0}", entryFileName);
byte[] buffer = new byte[4096];
String fullZipToPath = Path.Combine(outputfolder, entryFileName);
string directoryName = Path.GetDirectoryName(fullZipToPath);
if (directoryName.Length > 0)
{
Directory.CreateDirectory(directoryName);
}
using (FileStream streamWriter = File.Create(fullZipToPath))
{
StreamUtils.Copy(zipInputStream, streamWriter, buffer);
}
zipEntry = zipInputStream.GetNextEntry();
}
}
catch (Exception ex)
{
_logger.Error("Error during extraction",ex);
throw;
}
}
Any idea how to fix this problem?
I had this same issue when decompressing a zip-file made with 7-zip.
I changed it from Deflate64 to Deflate, and then it worked.
We have a page that users can download media and we construct a folder structure similar to the following and zip it up and send it back to the user in the response.
ZippedFolder.zip
- Folder A
- File 1
- File 2
- Folder B
- File 3
- File 4
The existing implementation that accomplishes this saves files and directories temporarily to file system and then deletes them at the end. We are trying to get away from doing this and would like to accomplish this entirely in memory.
I am able to successfully create a ZipFile with files in it, but the problem I am running into is creating Folder A and Folder B and adding files to those and then adding those two folders to the Zip File.
How can I do this without saving to the file system?
The code for just saving the file streams to the zip file and then setting the Output Stream on the response is the following.
public Stream CompressStreams(IList<Stream> Streams, IList<string> StreamNames, Stream OutputStream = null)
{
MemoryStream Response = null;
using (ZipFile ZippedFile = new ZipFile())
{
for (int i = 0, length = Streams.Count; i < length; i++)
{
ZippedFile.AddEntry(StreamNames[i], Streams[i]);
}
if (OutputStream != null)
{
ZippedFile.Save(OutputStream);
}
else
{
Response = new MemoryStream();
ZippedFile.Save(Response);
// Move the stream back to the beginning for reading
Response.Seek(0, SeekOrigin.Begin);
}
}
return Response;
}
EDIT We are using DotNetZip for the zipping/unzipping library.
Here's another way of doing it using System.IO.Compression.ZipArchive
public Stream CompressStreams(IList<Stream> Streams, IList<string> StreamNames, Stream OutputStream = null)
{
MemoryStream Response = new MemoryStream();
using (ZipArchive ZippedFile = new ZipArchive(Response, ZipArchiveMode.Create, true))
{
for (int i = 0, length = Streams.Count; i < length; i++)
using (var entry = ZippedFile.CreateEntry(StreamNames[i]).Open())
{
Streams[i].CopyTo(entry);
}
}
if (OutputStream != null)
{
Response.Seek(0, SeekOrigin.Begin);
Response.CopyTo(OutputStream);
}
return Response;
}
and a little test:
using (var write = new FileStream(#"C:\users\Public\Desktop\Testzip.zip", FileMode.OpenOrCreate, FileAccess.Write))
using (var read = new FileStream(#"C:\windows\System32\drivers\etc\hosts", FileMode.Open, FileAccess.Read))
{
CompressStreams(new List<Stream>() { read }, new List<string>() { #"A\One.txt" }, write);
}
re: your comment -- sorry, not sure if it creates something in the background, but you're not creating it yourself to do anything
I'm working with a file stream in C#. It's a storage cache, so if something goes bad writing the file (corrupted data, ...), I need to delete the file and rethrow the exception to report the problem. I'm thinking on how to implement it in the best way. My first attempt was:
Stream fileStream = null;
try
{
fileStream = new FileStream(GetStorageFile(),
FileMode.Create, FileAccess.Write, FileShare.Write);
//write the file ...
}
catch (Exception ex)
{
//Close the stream first
if (fileStream != null)
{
fileStream.Close();
}
//Delete the file
File.Delete(GetStorageFile());
//Re-throw exception
throw;
}
finally
{
//Close stream for the normal case
if (fileStream != null)
{
fileStream.Close();
}
}
As you will see, if something goes bad writing the file, the fileStream will be closed twice. I know that it works, but I don't think that is the best implementation.
I think that I could remove the finally block, and close the stream in the try block, but I have posted this here because you guys are experts and I want to hear the voice of an expert.
If you put the fileStream in a using block you don't need to worry about closing it, and then just leave the cleaning up (deleting of the file in the catch block.
try
{
using (FileStream fileStream = new FileStream(GetStorageFile(),
FileMode.Create, FileAccess.Write, FileShare.Write))
{
//write the file ...
}
}
catch (Exception ex)
{
File.Delete(GetStorageFile());
//Re-throw exception
throw;
}
I believe what you want is this:
var fs = new FileStream(result.FilePath, FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose);
I've used it with ASP.Net to have the web server return a result to a temp file that's on disk, but to make sure it's cleaned up after the web server finishes serving it to the client.
public static IActionResult TempFile(string tempPath, string mimeType, string fileDownloadName)
{
var fs = new FileStream(tempPath, FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose);
var actionResult = new FileStreamResult(fileStream: fs, contentType: mimeType)
{
FileDownloadName = fileDownloadName
};
return actionResult;
}