浏览代码

已完成文件打包功能,准备拆包

yuzhengyang 8 年之前
父节点
当前提交
cebdaf2faf

+ 2 - 1
Fork.Net/Oreo.Plugins/Oreo.FileMan/Views/MainForm.cs

@@ -102,7 +102,8 @@ namespace Oreo.FileMan.Views
 
             //string b = @"D:\Temp\测试压缩\Root\Plugin\NetAssist.exe.gz";
             //FileCompressTool.Decompress(b);
-
+            //FilePackageTool.Pack(@"D:\Temp\测试压缩\Root2", @"D:\Temp\测试压缩\Root2.pkg");
+            FilePackageTool.Unpack(@"D:\Temp\测试压缩\Root2.pkg", @"D:\Temp\测试压缩\Root2");
         } 
     }
 }

+ 33 - 0
Fork.Net/Y.Utils/IOUtils/FileUtils/FilePackageModel.cs

@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Y.Utils.IOUtils.FileUtils
+{
+     class FilePackageModel
+    {
+        public string Name { get; set; }
+        public string Path { get; set; }
+        public string MD5 { get; set; }
+        public long Size { get; set; }
+        public byte[] NameByte { get { return Encoding.Default.GetBytes(Name); } }
+        public byte[] PathByte { get { return Encoding.Default.GetBytes(Path); } }
+        public byte[] MD5Byte { get { return Encoding.Default.GetBytes(MD5); } }
+        public byte[] SizeByte { get { return BitConverter.GetBytes(Size); } }
+        public byte[] NameLengthByte { get { return BitConverter.GetBytes(NameByte.Length); } }
+        public byte[] PathLengthByte { get { return BitConverter.GetBytes(PathByte.Length); } }
+        public byte[] MD5LengthByte { get { return BitConverter.GetBytes(MD5Byte.Length); } }
+        public byte[] SizeLengthByte { get { return BitConverter.GetBytes(SizeByte.Length); } }
+        public int AllByteLength
+        {
+            get
+            {
+                return NameByte.Length + PathByte.Length +
+                    MD5Byte.Length + SizeByte.Length +
+                    NameLengthByte.Length + PathLengthByte.Length +
+                    MD5LengthByte.Length + SizeLengthByte.Length;
+            }
+        }
+    }
+}

+ 141 - 13
Fork.Net/Y.Utils/IOUtils/FileUtils/FilePackageTool.cs

@@ -15,6 +15,7 @@ using System.Resources;
 using System.Runtime.Serialization.Formatters.Binary;
 using System.Text;
 using Y.Utils.DataUtils.Collections;
+using Y.Utils.IOUtils.PathUtils;
 
 namespace Y.Utils.IOUtils.FileUtils
 {
@@ -23,7 +24,7 @@ namespace Y.Utils.IOUtils.FileUtils
     /// </summary>
     public class FilePackageTool
     {
-        private static string FileTypeDesc = "FilePackage [文件打包]";
+        private static string FileTypeDesc = "FilePackage";
         private static int FileBuffer = 1024 * 1024;
 
         #region 类型单一,文件处理复杂,加载占用超大内存(这都是辣鸡)
@@ -142,7 +143,7 @@ namespace Y.Utils.IOUtils.FileUtils
         /// -11;//要打包的路径不存在
         /// -12;//打包后的目标文件已存在
         /// -13;//要打包的路径中没有文件
-        /// -21;//读取文件大小异常
+        /// -404;//未知错误,操作失败
         /// </returns>
         public static int Pack(string srcPath, string dstFile, bool overwrite = true)
         {
@@ -150,33 +151,70 @@ namespace Y.Utils.IOUtils.FileUtils
             if (!Directory.Exists(srcPath)) return -11;//要打包的路径不存在
             if (File.Exists(dstFile) && !overwrite) return -12;//打包后的目标文件已存在
 
-            List<string> allfile = FileTool.GetAllFile(srcPath);
-            if (ListTool.HasElements(allfile))
+            List<string> tempfiles = FileTool.GetAllFile(srcPath);
+            List<FilePackageModel> files = new List<FilePackageModel>();
+            if (ListTool.HasElements(tempfiles))
             {
-                //读取所有文件的文件大小并检查
-                long[] filesize = FileTool.Size(allfile);
-                foreach (var fs in filesize) { if (fs < 0) return -21; }//读取文件大小异常
-                //读取所有文件的MD5码
-                string[] filemd5 = FileTool.GetMD5(allfile);
+                //汇总所有文件
+                tempfiles.ForEach(x =>
+                {
+                    files.Add(new FilePackageModel()
+                    {
+                        Name = Path.GetFileName(x),
+                        Path = DirTool.GetFilePath(x),
+                        Size = FileTool.Size(x),
+                        MD5 = FileTool.GetMD5(x),
+                    });
+                });
 
+                long allfilesize = files.Sum(x => x.Size);
                 using (FileStream fsWrite = new FileStream(dstFile, FileMode.Create))
                 {
-                    allfile.ForEach(x =>
+                    //写入头部总长度
+                    int headl = files.Sum(x => x.AllByteLength);
+                    byte[] headlength = BitConverter.GetBytes(headl);
+                    fsWrite.Write(headlength, 0, headlength.Length);
+                    //循环写入文件信息
+                    files.ForEach(x =>
                     {
-                        using (FileStream fsRead = new FileStream(x, FileMode.Open))
+                        fsWrite.Write(x.NameLengthByte, 0, x.NameLengthByte.Length);
+                        fsWrite.Write(x.NameByte, 0, x.NameByte.Length);
+                        fsWrite.Write(x.PathLengthByte, 0, x.PathLengthByte.Length);
+                        fsWrite.Write(x.PathByte, 0, x.PathByte.Length);
+                        fsWrite.Write(x.SizeLengthByte, 0, x.SizeLengthByte.Length);
+                        fsWrite.Write(x.SizeByte, 0, x.SizeByte.Length);
+                        fsWrite.Write(x.MD5LengthByte, 0, x.MD5LengthByte.Length);
+                        fsWrite.Write(x.MD5Byte, 0, x.MD5Byte.Length);
+                    });
+                    //循环写入文件
+                    files.ForEach(x =>
+                    {
+                        using (FileStream fsRead = new FileStream(DirTool.Combine(x.Path, x.Name), FileMode.Open))
                         {
+                            int readCount = 0;
+                            byte[] buffer = new byte[FileBuffer];
+                            while ((readCount = fsRead.Read(buffer, 0, buffer.Length)) > 0)
+                            {
+                                fsWrite.Write(buffer, 0, readCount);
+                                allfilesize -= readCount;
+                            }
                             fsRead.Close();
                         }
                     });
                     fsWrite.Close();
                 }
+                if (allfilesize == 0)
+                {
+                    return (int)Math.Ceiling((DateTime.Now - beginTime).TotalSeconds);//操作成功
+                }
             }
             else
             {
                 return -13;//要打包的路径中没有文件
             }
-
-            return (int)Math.Ceiling((DateTime.Now - beginTime).TotalSeconds);//操作成功
+            //打包失败后,删除打包后的文件
+            try { File.Delete(dstFile); } catch (Exception e) { }
+            return -404;//未知错误,操作失败
         }
         /// <summary>
         /// 解包
@@ -188,6 +226,96 @@ namespace Y.Utils.IOUtils.FileUtils
             if (!File.Exists(srcFile)) return -11; //要解包的文件不存在
             if (Directory.Exists(dstPath) && !overwrite) return -12;//要解包的目标文件夹已存在
 
+            using (FileStream fsRead = new FileStream(srcFile, FileMode.Open))
+            {
+                //读取头部总长度
+                byte[] headl = new byte[4];
+                int headlength = 0;
+                fsRead.Read(headl, 0, headl.Length);
+                headlength = BitConverter.ToInt32(headl, 0);
+                if (headlength > 0)
+                {
+                    //读取文件列表信息
+                    byte[] headdata = new byte[headlength];
+                    List<FilePackageModel> files = new List<FilePackageModel>();
+                    fsRead.Read(headdata, 0, headlength);
+
+                    int index = 0;
+                    while (index < headlength)
+                    {
+                        #region 读取文件名长度和内容
+                        //文件名长度
+                        byte[] namelengthbyte = new byte[4];
+                        Buffer.BlockCopy(headdata, index, namelengthbyte, 0, namelengthbyte.Length);
+                        int namelength = BitConverter.ToInt32(namelengthbyte, 0);
+                        index += namelengthbyte.Length;
+
+                        //文件名内容
+                        byte[] namebyte = new byte[namelength];
+                        Buffer.BlockCopy(headdata, index, namebyte, 0, namelength);
+                        string name = Encoding.Default.GetString(namebyte);
+                        index += namebyte.Length;
+                        #endregion
+
+                        #region 读取路径长度和内容
+                        //路径长度
+                        byte[] pathlengthbyte = new byte[4];
+                        Buffer.BlockCopy(headdata, index, pathlengthbyte, 0, pathlengthbyte.Length);
+                        int pathlength = BitConverter.ToInt32(pathlengthbyte, 0);
+                        index += pathlengthbyte.Length;
+
+                        //路径内容
+                        byte[] pathbyte = new byte[pathlength];
+                        Buffer.BlockCopy(headdata, index, pathbyte, 0, pathlength);
+                        string path = Encoding.Default.GetString(pathbyte);
+                        index += pathbyte.Length;
+                        #endregion
+
+                        #region 读取文件大小长度和内容
+                        //文件大小长度
+                        byte[] sizelengthbyte = new byte[4];
+                        Buffer.BlockCopy(headdata, index, sizelengthbyte, 0, sizelengthbyte.Length);
+                        int sizelength = BitConverter.ToInt32(sizelengthbyte, 0);
+                        index += sizelengthbyte.Length;
+
+                        //文件大小
+                        byte[] sizebyte = new byte[sizelength];
+                        Buffer.BlockCopy(headdata, index, sizebyte, 0, sizelength);
+                        int size = BitConverter.ToInt32(sizebyte, 4);
+                        index += sizebyte.Length;
+                        #endregion
+
+                        #region 读取文件MD5码长度和内容
+                        //文件大小长度
+                        byte[] md5lengthbyte = new byte[4];
+                        Buffer.BlockCopy(headdata, index, md5lengthbyte, 0, md5lengthbyte.Length);
+                        int md5length = BitConverter.ToInt32(md5lengthbyte, 0);
+                        index += md5lengthbyte.Length;
+
+                        //文件大小
+                        byte[] md5byte = new byte[md5length];
+                        Buffer.BlockCopy(headdata, index, md5byte, 0, md5length);
+                        string md5 = Encoding.Default.GetString(md5byte);
+                        index += md5byte.Length;
+                        #endregion
+
+                        files.Add(new FilePackageModel()
+                        {
+                            Name = name,
+                            Path = path,
+                            Size = size,
+                            MD5 = md5,
+                        });
+                    }
+
+                    int a = 111;
+
+                    //fsWrite.Write(x.SizeLengthByte, 0, x.SizeLengthByte.Length);
+                    //fsWrite.Write(x.SizeByte, 0, x.SizeByte.Length);
+                    //fsWrite.Write(x.MD5LengthByte, 0, x.MD5LengthByte.Length);
+                    //fsWrite.Write(x.MD5Byte, 0, x.MD5Byte.Length);
+                }
+            }
             return (int)Math.Ceiling((DateTime.Now - beginTime).TotalSeconds);//操作成功
         }
     }

+ 2 - 2
Fork.Net/Y.Utils/IOUtils/FileUtils/FileTool.cs

@@ -238,8 +238,8 @@ namespace Y.Utils.IOUtils.FileUtils
         /// <returns></returns>
         public static string[] GetMD5(List<string> files)
         {
-            string[] result = new string[files.Length];
-            for (int i = 0; i < files.Length; i++)
+            string[] result = new string[files.Count];
+            for (int i = 0; i < files.Count; i++)
             {
                 result[i] = GetMD5(files[i]);
             }

+ 1 - 0
Fork.Net/Y.Utils/Y.Utils.csproj

@@ -53,6 +53,7 @@
   <ItemGroup>
     <Compile Include="AppUtils\AppUnique.cs" />
     <Compile Include="IOUtils\FileUtils\FileCompressTool.cs" />
+    <Compile Include="IOUtils\FileUtils\FilePackageModel.cs" />
     <Compile Include="IOUtils\FileUtils\FilePackageTool.cs" />
     <Compile Include="NetUtils\NetManUtils\NetConnectionInfo.cs" />
     <Compile Include="NetUtils\NetManUtils\NetFlowService.cs" />