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
}
}