using ICSharpCode.SharpZipLib.Checksum; using ICSharpCode.SharpZipLib.Zip; using SmartCoalApplication.Base.CommTool; using SmartCoalApplication.Base.Functionodel; using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Xml.Serialization; using static SmartCoalApplication.Base.Functionodel.ZipXmlModel; namespace SmartCoalApplication.Base.CommTool { /// /// 操作压缩包 /// public class ZipHandleHelper { public string zipName; private ZipFile zipFile; public ZipHandleHelper(string fileName) { this.zipName = fileName; if (zipName != null) zipFile = new ZipFile(File.OpenRead(zipName), true); } /// /// 从压缩包获取图片序列xml文件 /// /// public ZipXmlModel GetXmlFromZip() { if (zipFile != null) { ZipEntry zipEntry = zipFile.GetEntry("z-index.xml");//固定的xml文件名 if (zipEntry == null) return null; using (Stream stream = zipFile.GetInputStream(zipEntry)) { StreamReader streamReader = new StreamReader(stream); string xmlNotes = streamReader.ReadToEnd(); ZipXmlModel zipXmlModel = XmlSerializeHelper.DESerializer(xmlNotes); streamReader.Dispose(); return zipXmlModel; } } else return null; } ///// ///// 从压缩包获取标注和测量的xml ///// ///// ///// //public PicConfigModel GetImageXmlFromZip() //{ // if (zipFile != null) // { // ZipEntry zipEntry = zipFile.GetEntry("labelandmeasure.xml");//固定的标注和测量的xml // if (zipEntry == null) // return null; // using (Stream stream = zipFile.GetInputStream(zipEntry)) // { // StreamReader streamReader = new StreamReader(stream); // string xmlNotes = streamReader.ReadToEnd(); // PicConfigModel picConfigModel = XmlSerializeHelper.DESerializer(xmlNotes); // streamReader.Dispose(); // return picConfigModel; // } // } // else // return null; //} /// /// 从压缩包获取指定图片 /// /// /// public Image GetPicFromZip(string picName) { ZipInputStream inputStream = new ZipInputStream(File.OpenRead(zipName)); ZipEntry zipEntry = null; while ((zipEntry = inputStream.GetNextEntry()) != null) { if (zipEntry.Name == @"images/" + picName) { long size = zipEntry.Size; byte[] data = new byte[size]; while (true) { size = inputStream.Read(data, 0, data.Length); if (size <= 0) break; } MemoryStream ms = new MemoryStream(data); Image image = Image.FromStream(ms); ms.Dispose(); return image; } } return null; } /// /// 从压缩包删除指定图片 /// /// /// public bool DeletePicFromZip(string picName) { if(zipFile != null) { ZipEntry zipEntry = zipFile.GetEntry(@"images/" + picName); try { zipFile.BeginUpdate(); zipFile.Delete(zipEntry); zipFile.CommitUpdate();//有时会报错,不清楚原因 return true; } catch (Exception) { } } return false; } /// /// 修改压缩包中的图片序列xml /// /// public bool ModifyXmlNodes(ZipXmlModel zipXmlModel) { if (zipFile != null) { string xmlNotes = XmlSerializeHelper.XmlSerialize(zipXmlModel); try { zipFile.BeginUpdate(); zipFile.Add(new StateDataSource(xmlNotes), "z-index.xml"); zipFile.CommitUpdate();//有时会报错,不清楚原因 return true; } catch(Exception) { } } return false; } ///// ///// 修改压缩包中的标注和测量xml ///// ///// ///// //public bool ModifyLabelAndMeasureXml(PicConfigModel picConfigModel) //{ // if (zipFile != null) // { // string xmlNotes = XmlSerializeHelper.XmlSerialize(picConfigModel); // try // { // zipFile.BeginUpdate(); // zipFile.Add(new StateDataSource(xmlNotes), "labelandmeasure.xml"); // zipFile.CommitUpdate();//有时会报错,不清楚原因 // return true; // } // catch (Exception) // { // } // } // return false; //} /// /// 创建带xml和图片的新zip包 /// /// zip包存放的路径名称 /// 要打包的图片文件夹路径 /// public static string CompressedZipPackage(string imageDirectory) { string[] fileNames = Directory.GetFiles(imageDirectory); if(fileNames.Count() == 0) { MessageBox.Show("拍摄文件夹不存在或没有内容,打包失败"); return null; } //判断是否是图片对象 List imageList = new List(); foreach(string fileName in fileNames) { try { //本来是用来保证是图片的,但是太慢了。 //可以考虑读二进制的数据判断格式,但是麻烦 //暂时用文件名判断代替 //Image image = Image.FromFile(fileName); if (!Path.GetExtension(fileName).Equals(".xml")) { imageList.Add(fileName); } } catch(Exception) { } } if(imageList.Count == 0) { MessageBox.Show("拍摄文件夹内没有图片文件,打包失败"); return null; } //zip图片排序的xml ZipXmlModel zipXmlModel = new ZipXmlModel(); zipXmlModel.picNameList = new List(); //zip标注和测量的xml,不清楚初次创建是否需要添加其他信息 //PicConfigModel picConfigModel = new PicConfigModel(); //picConfigModel.hardware = new PicConfigModel.Hardware(); //picConfigModel.hardware.microscope = "显微镜"; //picConfigModel.hardware.objective = "物镜"; //picConfigModel.hardware.magnificationChanger = "变倍器"; //picConfigModel.hardware.exposureTime = "曝光时间"; //存放压缩包的路径 if (!Directory.Exists(Application.StartupPath + "\\temp")) Directory.CreateDirectory(Application.StartupPath + "\\temp"); string zipPath = Application.StartupPath + "\\temp\\图像采集-Z轴扫描-" + DateTime.Now.ToString("HHmmss") + ".tga"; try { using (ZipOutputStream zipOutputStream = new ZipOutputStream(File.Create(zipPath))) { zipOutputStream.SetLevel(6);//压缩等级1-9 foreach (string imageName in imageList) { //图片名称添加到xml中 PicName onePicName = new PicName(); onePicName.name = Path.GetFileName(imageName); zipXmlModel.picNameList.Add(onePicName); using (FileStream fs = File.OpenRead(imageName)) { byte[] buffer = new byte[4 * 1024];//缓冲区,每次操作大小 string newName = ""; newName = @"images/" + Path.GetFileName(imageName); ZipEntry entry = new ZipEntry(newName);//创建压缩包内的文件 entry.DateTime = DateTime.Now;//文件创建时间 zipOutputStream.PutNextEntry(entry);//将文件写入压缩包 int sourceBytes; do { sourceBytes = fs.Read(buffer, 0, buffer.Length);//读取文件内容(1次读4M,写4M) zipOutputStream.Write(buffer, 0, sourceBytes);//将文件内容写入压缩相应的文件 } while (sourceBytes > 0); } } zipOutputStream.CloseEntry(); } //zipout的流对象未找到向zip包内添加非本地文件的方法 //固先将图片打包到zip中,然后使用zipfile对象添加两个xml using (ZipFile zFile = new ZipFile(File.OpenRead(zipPath), true)) { string xmlNotes = XmlSerializeHelper.XmlSerialize(zipXmlModel); //string labelAndMeasureNotes = XmlSerializeHelper.XmlSerialize(picConfigModel); zFile.BeginUpdate(); zFile.Add(new StateDataSource(xmlNotes), "z-index.xml"); //zFile.Add(new StateDataSource(labelAndMeasureNotes), "labelandmeasure.xml"); zFile.CommitUpdate();//有时会报错,不清楚原因 } } catch(Exception) { if (File.Exists(zipPath)) File.Delete(zipPath); MessageBox.Show("打包保存失败"); return ""; } return zipPath; } /// /// 自定义实现IStaticDataSource接口的类 /// class StateDataSource : IStaticDataSource { string source; public StateDataSource(string source) { this.source = source; } public Stream GetSource() { byte[] array = Encoding.UTF8.GetBytes(source);//使用asc2会中文乱码 MemoryStream stream = new MemoryStream(array); return stream; } } #region [生成压缩包] /// /// /// public static void createZip(string fileName, string outFileName) { if (fileName[fileName.Length - 1] != Path.DirectorySeparatorChar) { fileName += Path.DirectorySeparatorChar; } ZipOutputStream outstream = new ZipOutputStream(File.Create(outFileName)); outstream.SetLevel(6); zip(fileName, outstream, fileName); outstream.Finish(); outstream.Close(); } public static void zip(string strFile, ZipOutputStream outstream, string staticFile) { if (strFile[strFile.Length - 1] != Path.DirectorySeparatorChar) { strFile += Path.DirectorySeparatorChar; } Crc32 crc = new Crc32(); //获取指定目录下所有文件和子目录文件名称 string[] filenames = Directory.GetFileSystemEntries(strFile); //遍历文件 foreach (string file in filenames) { if (Directory.Exists(file)) { zip(file, outstream, staticFile); } //否则,直接压缩文件 else { //打开文件 FileStream fs = File.OpenRead(file); //定义缓存区对象 byte[] buffer = new byte[fs.Length]; //通过字符流,读取文件 fs.Read(buffer, 0, buffer.Length); //得到目录下的文件(比如:D:\Debug1\test),test string tempfile = file.Substring(staticFile.LastIndexOf("\\") + 1); ZipEntry entry = new ZipEntry(tempfile); entry.DateTime = DateTime.Now; entry.Size = fs.Length; fs.Close(); crc.Reset(); crc.Update(buffer); entry.Crc = crc.Value; outstream.PutNextEntry(entry); //写文件 outstream.Write(buffer, 0, buffer.Length); } } } #endregion #region [解压压缩包] /// /// /// public static bool decompressionZip(string TargetFile, string fileDir) { string rootFile = ""; bool success = false; try { //读取压缩文件(zip文件),准备解压缩 ZipInputStream inputstream = new ZipInputStream(File.OpenRead(TargetFile.Trim())); ZipEntry entry; string path = fileDir; //解压出来的文件保存路径 string rootDir = ""; //根目录下的第一个子文件夹的名称 while ((entry = inputstream.GetNextEntry()) != null) { rootDir = Path.GetDirectoryName(entry.Name); //得到根目录下的第一级子文件夹的名称 if (rootDir.IndexOf("\\") >= 0) { rootDir = rootDir.Substring(0, rootDir.IndexOf("\\") + 1); } string dir = Path.GetDirectoryName(entry.Name); //得到根目录下的第一级子文件夹下的子文件夹名称 string fileName = Path.GetFileName(entry.Name); //根目录下的文件名称 if (dir != "") { //创建根目录下的子文件夹,不限制级别 if (!Directory.Exists(fileDir + "\\" + dir)) { path = fileDir + "\\" + dir; //在指定的路径创建文件夹 Directory.CreateDirectory(path); } } else if (dir == "" && fileName != "") { //根目录下的文件 path = fileDir; rootFile = fileName; } else if (dir != "" && fileName != "") { //根目录下的第一级子文件夹下的文件 if (dir.IndexOf("\\") > 0) { //指定文件保存路径 path = fileDir + "\\" + dir; } } if (dir == rootDir) { //判断是不是需要保存在根目录下的文件 path = fileDir + "\\" + rootDir; } //以下为解压zip文件的基本步骤 //基本思路:遍历压缩文件里的所有文件,创建一个相同的文件 if (fileName != String.Empty) { FileStream fs = File.Create(path + "\\" + fileName); int size = 2048; byte[] data = new byte[2048]; while (true) { size = inputstream.Read(data, 0, data.Length); if (size > 0) { fs.Write(data, 0, size); } else { break; } } fs.Close(); } } inputstream.Close(); success = true; } catch (Exception ex) { } return success; } #endregion } }