主要是在原来项目上有个需求,需要对多个文件进行打包成一个。
因此,我手工写了一个纯c#代码的多个文件打包算法。
代码也很简单,自行参考如下。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace BaseHelper.Base
{
public class ZipHelper
{
public static string Error;
public static bool Zip(string FilePath, string Folder)
{
Error = "";
if (!Directory.Exists(Folder))
{
Error = "目标文件夹丢失!";
return false;
}
if (File.Exists(FilePath))
{
try
{
File.Delete(FilePath);
}
catch
{
}
}
try
{
string fileHeader = Scan(Folder, "");
if (fileHeader.Length > 0)
fileHeader = fileHeader.Substring(0, fileHeader.Length - 1);
byte[] zipFileName = Encoding.Default.GetBytes(Convert.ToBase64String(Encoding.Default.GetBytes(fileHeader)));
byte[] zipHeaderLength = Encoding.ASCII.GetBytes(zipFileName.Length.ToString());
byte[] zipHeader = new byte[10];
Array.Copy(zipHeaderLength, 0, zipHeader, zipHeader.Length - zipHeaderLength.Length, zipHeaderLength.Length);
Stream stream = File.OpenWrite(FilePath);
BinaryWriter bw = new BinaryWriter(stream);
bw.Write(zipHeader, 0, 10);
bw.Write(zipFileName, 0, zipFileName.Length);
string[] files = fileHeader.Split('|');
foreach (string file in files)
{
string[] sp = file.Split(',');
string fullName = Folder + sp[0];
long fileSize = Convert.ToInt64(sp[1]);
Stream fileStream = File.OpenRead(fullName);
BinaryReader fileRead = new BinaryReader(fileStream);
byte[] buffer = new byte[8192];
long blockCount = fileSize / buffer.Length;
int blockRemain = Convert.ToInt32(fileSize % buffer.Length);
for (int i = 0; i < blockCount; i++)
{
buffer = fileRead.ReadBytes(buffer.Length);
bw.Write(buffer, 0, buffer.Length);
bw.Flush();
}
if (blockRemain > 0)
{
buffer = fileRead.ReadBytes(blockRemain);
bw.Write(buffer, 0, buffer.Length);
bw.Flush();
}
fileRead.Close();
fileStream.Close();
}
bw.Close();
stream.Close();
return true;
}
catch (Exception ex)
{
Error = ex.Message;
return false;
}
}
private static string Scan(string ParentFolder, string Folder)
{
string fileHeader = "";
DirectoryInfo dinfo = new DirectoryInfo(ParentFolder + Folder);
foreach (FileInfo f in dinfo.GetFiles())
{
fileHeader += Folder + f.Name + "," + f.Length.ToString() + "|";
}
foreach (DirectoryInfo d in dinfo.GetDirectories())
{
fileHeader += Scan(ParentFolder, d.Name + "\\");
}
return fileHeader;
}
public static bool UnZip(string FilePath, string Folder)
{
Error = "";
if (!File.Exists(FilePath))
{
Error = "目标包不存在!";
return false;
}
if (!Directory.Exists(Folder))
Directory.CreateDirectory(Folder);
try
{
if (Folder.LastIndexOf("\\") != (Folder.Length - 1))
Folder += "\\";
Stream stream = File.OpenRead(FilePath);
BinaryReader br = new BinaryReader(stream);
byte[] zipHeader = br.ReadBytes(10);
string b = Encoding.ASCII.GetString(zipHeader).Replace("\0", "").Trim();
int zipHeaderLength = Convert.ToInt32(b);
byte[] zipFileName = br.ReadBytes(zipHeaderLength);
string fileHeader = Encoding.Default.GetString(Convert.FromBase64String(Encoding.ASCII.GetString(zipFileName)));
if (!fileHeader.Contains("|"))
return false;
string[] files = fileHeader.Split('|');
for (int i = 0; i < files.Length; i++)
{
try
{
string[] sp = files[i].Split(',');
FileInfo finfo = new FileInfo(Folder + sp[0]);
if (!Directory.Exists(finfo.DirectoryName))
Directory.CreateDirectory(finfo.DirectoryName);
long fileSize = Convert.ToInt64(sp[1]);
if (finfo.Exists)
{
try
{
finfo.Delete();
}
catch { }
}
Stream fileStream = File.OpenWrite(finfo.FullName);
BinaryWriter fileWrite = new BinaryWriter(fileStream);
byte[] buffer = new byte[8192];
long blockCount = fileSize / buffer.Length;
int blockRemain = Convert.ToInt32(fileSize % buffer.Length);
for (int j = 0; j < blockCount; j++)
{
buffer = br.ReadBytes(buffer.Length);
fileWrite.Write(buffer, 0, buffer.Length);
fileWrite.Flush();
}
if (blockRemain > 0)
{
buffer = br.ReadBytes(blockRemain);
fileWrite.Write(buffer, 0, buffer.Length);
fileWrite.Flush();
}
fileWrite.Close();
fileStream.Close();
}
catch (Exception exx)
{
Error = exx.Message;
Console.WriteLine(exx.Message);
}
}
br.Close();
return true;
}
catch (Exception ex)
{
Error = ex.Message;
return false;
}
}
}
}