i would like to zip the multiple files in the folder , however my code below was working but its not zip the files and im not sure what goings on as it getting null value . Kindly advise
private static string filepath = string.IsNullOrEmpty(ConfigurationManager.AppSettings["AConvert"])
? "" : ConfigurationManager.AppSettings["AConvert"];
static void Main(string[] args)
{
string zipFileName;
string fileExt;
try
{
fileExt = Path.GetExtension(filepath);
zipFileName = filepath.Replace(fileExt + DateTime.Now.ToString("MMyy"), ".zip");
using (ZipOutputStream s = new ZipOutputStream(File.Create(zipFileName)))
{
s.Password = "ABC123";
s.SetLevel(4); // 0 - store only to 9 - means best compression
byte[] buffer = new byte[4096];
ZipEntry entry = new ZipEntry(Path.GetFileName(filepath));
entry.DateTime = DateTime.Now;
s.PutNextEntry(entry);
using (FileStream fs = File.OpenRead(filepath))
{
int sourceBytes;
do
{
sourceBytes = fs.Read(buffer, 0, buffer.Length);
s.Write(buffer, 0, sourceBytes);
} while (sourceBytes > 0);
}
s.Finish();
s.Close();
}
}
catch (Exception ex)
{
Console.WriteLine("Exception during processing {0}", ex);
}
}
Not sure what your input is here, but I suspect you might want to use Path.GetFileName() instead of Path.GetExtension.
You are currently just getting an empty string, since "D:\Report" does not have an extention.
Furthermore, I believe you would have to do this for each file in the directory, and not just for the directory as a whole, if you want to zip the files that way.
Personally I would recommend you take a look at the dotnetzip library instead. It has some brilliantly simple ways to create zip-archives and add files to it. In your case, basically something like:
var yourListOfFilePaths = Directory.GetFiles(pathToYourDir);
using (ZipFile zip = new ZipFile())
{
foreach(string filePath in yourListOfFilePaths)
{
zip.AddFile(filePath);
}
zip.Save(pathToTargetDir + "\\MyZipFile.zip");
}
PS: You can find more C# examples for DotNetZip here.
ok guys , its working right now . here the code that i amend from the Kjartan. Thanks
private static string filepath = string.IsNullOrEmpty(ConfigurationManager.AppSettings["AConvert"]) ? "" : ConfigurationManager.AppSettings["AConvert"];
private static string ZipPath = string.IsNullOrEmpty(ConfigurationManager.AppSettings["PathZip"]) ? "" : ConfigurationManager.AppSettings["PathZip"];
static void Main(string[] args)
{
var yourListOfFilePaths = Directory.GetFiles(filepath);
using (ZipFile zip = new ZipFile())
{
foreach (string filePath in yourListOfFilePaths)
{
zip.AddFile(filePath);
}
zip.Save(ZipPath + "\\Batch" + DateTime.Now.ToString("ddmmyy") + ".zip");
}
Related
I'm doing a c# wcf service in which I receive a bunch of images and the service merge them in a multiimage Tiff file. At the end of the service I want to delete the original files but I'm receiving an error that some other process is locking the file.
This is the code that receives the images (as a byte[] list) and write them to disk
public static List<string> SaveByteImagesToFile(List<byte[]> bytesToCopyIntoFiles, string imageReferenceType, string imageReferenceValue)
{
_applicationLogger.Debug(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name);
string imageFinalPath = string.Empty;
string joinImagesFilePath = string.Empty;
List<string> imagesFilePath = new List<string>();
int count = 1;
try
{
if (bytesToCopyIntoFiles.Count == 0)
{
throw new ArgumentNullException("bytesToCopyIntoFiles");
}
else
{
joinImagesFilePath = SettingsManager.GetServiceSetting(AppSettingsKeys.CopyImagesToFilePath, "NO_VALID_FILEPATH");
if (joinImagesFilePath.IsValidFilePath(out string errorMessage, true, true))
{
foreach (byte[] image in bytesToCopyIntoFiles)
{
var imageFileName = imageReferenceType + "_" + imageReferenceValue + "_" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + count.ToString();
imageFinalPath = joinImagesFilePath + Path.DirectorySeparatorChar + imageFileName + ".tiff";
using (FileStream stream = new FileStream(imageFinalPath, FileMode.Create, FileAccess.ReadWrite))
{
stream.Write(image, 0, image.Length);
stream.Flush();
}
imagesFilePath.Add(imageFinalPath);
count++;
}
}
else
{
exceptionMessageType = MainRepository.GetExceptionMessage("E171");
throw new IOException(exceptionMessageType.ExceptionMessage + " " + errorMessage);
}
}
return imagesFilePath;
}
catch
{
throw;
}
}
How or what can I use to prevent the service or any process to lock the file. As you can see I'm using the using scope for filestream without any luck.
Any ideas? Thanks
Resolved! By organizing the files in a certain order, when creating the multipage tiff, by the time the logic ends the worker already unlock the resources and I'm able now to delete them without any issue.
I am facing a issue in my code. PFA my code below
// Extract Zip File
public static void Extract(string zipFileName, string destinationPath)
{
ZipFile zipfile = new ZipFile(zipFileName);
List<ZipEntry> zipFiles= GetZipFiles(zipfile);
foreach (ZipEntry zipFile in zipFiles)
{
if (!zipFile.isDirectory())
{
java.io.InputStream s=zipfile.getInputStream(zipFile);
//InputStream s = zipfile.getInputStream(zipFile);
try
{
Directory.CreateDirectory(destinationPath + "\\" + Path.GetDirectoryName(zipFile.getName()));
// Directory.CreateDirectory(destinationPath + "\ + Path.GetDirectoryName(zipFile.getName()));
//Directory.CreateDirectory(Path.GetDirectoryName(zipFile.getName()));
java.io.FileOutputStream dest = new java.io.FileOutputStream(Path.Combine(destinationPath + "\\" + Path.GetDirectoryName(zipFile.getName()),
//java.io.FileOutputStream dest = new java.io.FileOutputStream(Path.Combine(Path.GetDirectoryName(zipFile.getName()),
Path.GetFileName(zipFile.getName())));
try
{
int len = 0;
byte[] buffer = new byte[7168];
while ((len = s.read(buffer)) >= 0)
{
dest.write(buffer, 0, len);
}
}
finally
{
dest.close();
}
}
finally
{
s.close();
}
}
}
}
Issue is : In this class can any one tell me formatof "string zipFileName, string destinationPath " means : which pathformate be use in zipFileName and designationPath.
This code is used for Unzip file using J# in c# please help me as soon as possible
: here zipFilename is path file to be ziped and destinationPath is path where file to be unzipped.
If I understand your question correctly, and you're working on Windows, then you would probably use a format like:
Extract(#"c:\myfolder\mysubfolder\myfile.zip", #"c:\mydestinationfolder\mysubfolder");
Give it a try and leave a comment to let me know if it works, or whatever else you've tried previously.
Are you using any compression libraries . For example the ZipFile - Is this any third party library ?
You can check compression libraries for C# that are available incase you plan to implement it.
I'm trying to extract an ISO to a folder with the same name without .iso on the end.
I'm having a problem with winrar as it will not start the extract when I start up with the seach starting in the folder with the ISO.
UPDATED with answer code
private void ExtractISO(string toExtract, string folderName)
{
// reads the ISO
CDReader Reader = new CDReader(File.Open(toExtract, FileMode.Open), true);
// passes the root directory the folder name and the folder to extract
ExtractDirectory(Reader.Root, folderName /*+ Path.GetFileNameWithoutExtension(toExtract)*/ + "\\", "");
// clears reader and frees memory
Reader.Dispose();
}
private void ExtractDirectory(DiscDirectoryInfo Dinfo, string RootPath, string PathinISO)
{
if (!string.IsNullOrWhiteSpace(PathinISO))
{
PathinISO += "\\" + Dinfo.Name;
}
RootPath += "\\" + Dinfo.Name;
AppendDirectory(RootPath);
foreach (DiscDirectoryInfo dinfo in Dinfo.GetDirectories())
{
ExtractDirectory(dinfo, RootPath, PathinISO);
}
foreach (DiscFileInfo finfo in Dinfo.GetFiles())
{
using (Stream FileStr = finfo.OpenRead())
{
using (FileStream Fs = File.Create(RootPath + "\\" + finfo.Name)) // Here you can Set the BufferSize Also e.g. File.Create(RootPath + "\\" + finfo.Name, 4 * 1024)
{
FileStr.CopyTo(Fs, 4 * 1024); // Buffer Size is 4 * 1024 but you can modify it in your code as per your need
}
}
}
}
static void AppendDirectory(string path)
{
try
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
}
catch (DirectoryNotFoundException Ex)
{
AppendDirectory(Path.GetDirectoryName(path));
}
catch (PathTooLongException Ex)
{
AppendDirectory(Path.GetDirectoryName(path));
}
}
The user selects the folder to extract (.ISO) toExtract. I then use it in the Process.Start() in the background worker. That just seems to open the mounting software and doesn't extract the ISO to the desired folder name.
Thanks in advance for your help.
Or if anyone could give me a batch to extract the ISO instead and to call it from c# passing toExtract and the folder name that would be helpful too.
Thanks
If external Class Libraries are OK!
Then use SevenZipSharp or .NET DiscUtils to extract ISO's...
These two ClassLibraries can manage ISO and Extract them!
For DiscUtils you can find some codes for ISO Management [CDReader Class] at the Link I provided.
But For SevenZipSharp, Please Explore the ClassLibrary source and find the Code to Extract or Google to find it!
To get the Name of the folder just use Path.GetFileNameWithoutExtension((string)ISOFileName) which will return "ISOFile" for an iso named "ISOFile.iso". And then you can use it with your desired path.
UPDATE
Code To Extract ISO Image with DiscUtils :
using DiscUtils;
using DiscUtils.Iso9660;
void ExtractISO(string ISOName, string ExtractionPath)
{
using (FileStream ISOStream = File.Open(ISOName, FileMode.Open))
{
CDReader Reader = new CDReader(ISOStream, true, true);
ExtractDirectory(Reader.Root, ExtractionPath + Path.GetFileNameWithoutExtension(ISOName) + "\\", "");
Reader.Dispose();
}
}
void ExtractDirectory(DiscDirectoryInfo Dinfo, string RootPath, string PathinISO)
{
if (!string.IsNullOrWhiteSpace(PathinISO))
{
PathinISO += "\\" + Dinfo.Name;
}
RootPath += "\\" + Dinfo.Name;
AppendDirectory(RootPath);
foreach (DiscDirectoryInfo dinfo in Dinfo.GetDirectories())
{
ExtractDirectory(dinfo, RootPath, PathinISO);
}
foreach (DiscFileInfo finfo in Dinfo.GetFiles())
{
using (Stream FileStr = finfo.OpenRead())
{
using (FileStream Fs = File.Create(RootPath + "\\" + finfo.Name)) // Here you can Set the BufferSize Also e.g. File.Create(RootPath + "\\" + finfo.Name, 4 * 1024)
{
FileStr.CopyTo(Fs, 4 * 1024); // Buffer Size is 4 * 1024 but you can modify it in your code as per your need
}
}
}
}
static void AppendDirectory(string path)
{
try
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
}
catch (DirectoryNotFoundException Ex)
{
AppendDirectory(Path.GetDirectoryName(path));
}
catch (PathTooLongException Exx)
{
AppendDirectory(Path.GetDirectoryName(path));
}
}
Use It with Like This :
ExtractISO(ISOFileName, Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\");
Working! Tested By Me!
And Of Course You can always add more Optimization to the code...
This Code is Just a Basic One!
For UDF or for making Windows ISO Files after servicing(DISM) with out needs the above accepted answer is not working for me so i tried this working method with DiscUtils
using DiscUtils;
public static void ReadIsoFile(string sIsoFile, string sDestinationRootPath)
{
Stream streamIsoFile = null;
try
{
streamIsoFile = new FileStream(sIsoFile, FileMode.Open);
DiscUtils.FileSystemInfo[] fsia = FileSystemManager.DetectDefaultFileSystems(streamIsoFile);
if (fsia.Length < 1)
{
MessageBox.Show("No valid disc file system detected.");
}
else
{
DiscFileSystem dfs = fsia[0].Open(streamIsoFile);
ReadIsoFolder(dfs, #"", sDestinationRootPath);
return;
}
}
finally
{
if (streamIsoFile != null)
{
streamIsoFile.Close();
}
}
}
public static void ReadIsoFolder(DiscFileSystem cdReader, string sIsoPath, string sDestinationRootPath)
{
try
{
string[] saFiles = cdReader.GetFiles(sIsoPath);
foreach (string sFile in saFiles)
{
DiscFileInfo dfiIso = cdReader.GetFileInfo(sFile);
string sDestinationPath = Path.Combine(sDestinationRootPath, dfiIso.DirectoryName.Substring(0, dfiIso.DirectoryName.Length - 1));
if (!Directory.Exists(sDestinationPath))
{
Directory.CreateDirectory(sDestinationPath);
}
string sDestinationFile = Path.Combine(sDestinationPath, dfiIso.Name);
SparseStream streamIsoFile = cdReader.OpenFile(sFile, FileMode.Open);
FileStream fsDest = new FileStream(sDestinationFile, FileMode.Create);
byte[] baData = new byte[0x4000];
while (true)
{
int nReadCount = streamIsoFile.Read(baData, 0, baData.Length);
if (nReadCount < 1)
{
break;
}
else
{
fsDest.Write(baData, 0, nReadCount);
}
}
streamIsoFile.Close();
fsDest.Close();
}
string[] saDirectories = cdReader.GetDirectories(sIsoPath);
foreach (string sDirectory in saDirectories)
{
ReadIsoFolder(cdReader, sDirectory, sDestinationRootPath);
}
return;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
it has extracted from a application source ISOReader but modified for my requirements
total source is available at http://www.java2s.com/Open-Source/CSharp_Free_CodeDownload/i/isoreader.zip
Try this:
string Desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
Process.Start("Winrar.exe", string.Format("x {0} {1}",
Desktop + "\\test.rar",
Desktop + "\\SomeFolder"));
That would extract the file test.rar to the folder SomeFolder. You can change the .rar extention to .iso, it'll work the same.
As far as I can see in your current code, there is no command given to extract a file, and no path to the file that has to be extracted. Try this example and let me know if it works =]
P.S. If you'd like to hide the extracting screen, you can set the YourProcessInfo.WindowStyle to ProcessWindowStyle.Hidden.
I hace confrunted recently with this kind of .iso extraction issue. After trying several methods, 7zip did the job for me, you just have to make sure that the latest version of 7zip is installed on your system. Maybe it will help
try
{
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = false;
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
cmd.Start();
cmd.StandardInput.WriteLine("C:");
//Console.WriteLine(cmd.StandardOutput.Read());
cmd.StandardInput.Flush();
cmd.StandardInput.WriteLine("cd C:\\\"Program Files\"\\7-Zip\\");
//Console.WriteLine(cmd.StandardOutput.ReadToEnd());
cmd.StandardInput.Flush();
cmd.StandardInput.WriteLine(string.Format("7z x -y -o{0} {1}", source, copyISOLocation.TempIsoPath));
//Console.WriteLine(cmd.StandardOutput.ReadToEnd());
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
cmd.WaitForExit();
Console.WriteLine(cmd.StandardOutput.ReadToEnd());
}
catch (Exception e)
{
Console.WriteLine(e.Message + "\n" + e.StackTrace);
if (e.InnerException != null)
{
Console.WriteLine(e.InnerException.Message + "\n" + e.InnerException.StackTrace);
}
}
I am using the library ICSharpCode.SharpZipLib.Zip;
My code is follows:
The path is root. \\ALAWP\\THIS\\ACORD\\
I'm zipping them to the ZIPDirectory
However when it's done the file is not named acord_combined.txt, instead it's called ACORD\acord_combined.txt
What am I doing wrong?
public void CleanRoot()
{
DirectoryInfo RootDi = new DirectoryInfo(FilePrep.RootDirectory);
string ZipDirectory = FilePrep.RootDirectory + "\\processed\\AceKey"+ DateTime.Now.ToString("yyyyMMdd_H;mm;ss") +".zip";
ZipOutputStream NewZipOutput = new ZipOutputStream(File.Create(ZipDirectory));
foreach (FileInfo fi in RootDi.GetFiles("acord*.*"))
{
Compress(ref NewZipOutput, fi);
//MoveFile(fi.FullName,ZipDirectory);
}
NewZipOutput.Finish();
NewZipOutput.Close();
}
public void Compress(ref ZipOutputStream ZipFolder, FileInfo fi)
{
try
{
FileStream fsFileToBeZipped = fi.OpenRead();
ZipEntry entry = new ZipEntry(fi.FullName);
ZipFolder.PutNextEntry(entry);
int size = 2048;
byte[] buffer = new byte[size];
while (true)
{
size = fsFileToBeZipped.Read(buffer, 0, buffer.Length);
if (size > 0)
ZipFolder.Write(buffer, 0, size);
else
break;
} //end while ( true )
fsFileToBeZipped.Close();
//prepare and delete file
fi.Attributes = FileAttributes.Normal;
//fi.Delete();
} //end try
catch (Exception e)
{
Console.WriteLine("Error zipping File. Error - " + e.Message);
} //end catch
}
Your problem is right here
new ZipEntry(fi.FullName);
The argument to zipEntry is the path in the zip file, not the full path the compressed data comes from. Usually zip libraries, such as 7zip and SharpZip, expose a way to create an "entry path" but the actual data written to the zip is from the full path.
Probably what you want is
new ZipEntry(Path.GetFileName(fi.fullName))
I've put together a quick test using the DotNetZip library which opens a zip file full of .bmp files and converts them to .jpg format.
Prior to this I was writing all of the files to a folder, converting them, saving out the jpg files & then removing the original bmp files, which got messy.
I'm no looking to unzip them in memory first, convert to jpg & then save.
The code works, but just isn't that quick. Can anyone give me any pointers as to what I can do to improve the code please? Also, Would threading help?
string zipToUnpack = "c:\\test\\1000.zip";
string unpackDirectory = "c:\\temp\\";
string f = string.Empty;
Bitmap bm;
MemoryStream ms;
using (ZipFile zip = ZipFile.Read(zipToUnpack))
{
foreach (ZipEntry e in zip)
{
if (e.FileName.ToLower().IndexOf(".bmp") > 0)
{
ms = new MemoryStream();
e.Extract(ms);
try
{
bm = new Bitmap(ms);
f = unpackDirectory + e.FileName.ToLower().Replace(".bmp", ".jpg");
bm.Save(f, System.Drawing.Imaging.ImageFormat.Jpeg);
}
catch (Exception ex)
{
Console.WriteLine("File: " + e.FileName + " " + ex.ToString());
}
ms.Dispose();
}
}
}
Thanks
In general, DotNetZip is single-threaded. You can open multiple archives in multiple threads, but each archive in only one thread.
If you want to enlist multiple CPUs or cores, then I can suggest calling QueueUserWorkItem for the part where you convert the data in the MemoryStream into a jpg.
The call to ZipEntry.Extract() needs to be done on the same thread, for all entries. This is because the Zipfile maintains a single FileStream for all read access, and multiple threads extracting entries will cause file pointer arithmetic errors.
So, something like this:
public class State
{
public string FileName;
public MemoryStream stream;
}
public void Run()
{
string unpackDirectory = "c:\\temp\\";
string zipToUnpack = "c:\\test\\1000.zip";
var ConvertImage = new WaitCallback( (o) => {
State s = o as State;
try
{
var bm = new Bitmap(s.stream);
var f = unpackDirectory + s.FileName.ToLower().Replace(".bmp", ".jpg");
bm.Save(f, System.Drawing.Imaging.ImageFormat.Jpeg);
}
catch (Exception ex)
{
Console.WriteLine("File: " + s.FileName + " " + ex.ToString());
}
});
using (ZipFile zip = ZipFile.Read(zipToUnpack))
{
foreach (ZipEntry e in zip)
{
if (e.FileName.ToLower().IndexOf(".bmp") > 0)
{
var ms = new MemoryStream();
e.Extract(ms);
ThreadPool.QueueUserWorkItem ( ConvertImage,
new State {
FileName = e.FileName, stream = ms }
});
}
}
}
}