|
|
@@ -28,115 +28,6 @@ namespace Y.Utils.IOUtils.FileUtils
|
|
|
const string FileVersion = "100001";//类型的版本 禁止修改长度(6位)
|
|
|
private static int FileBuffer = 1024 * 1024;
|
|
|
|
|
|
- #region 类型单一,文件处理复杂,加载占用超大内存(这都是辣鸡)
|
|
|
- /// <summary>
|
|
|
- /// 批量打包任意对象到资源文件
|
|
|
- /// </summary>
|
|
|
- /// <param name="objCollection">被打包对象的列表。键值对中键为其在资源文件中的唯一标示名。</param>
|
|
|
- /// <param name="targetFilePath">目标资源文件。默认参数为当前目录下的"MyRes.pck"文件。</param>
|
|
|
- /// <param name="overwrite">是否覆盖已存在的目标文件。默认=True</param>
|
|
|
- public static void ResourcePackage(IDictionary<string, object> objCollection, string targetFilePath, bool overwrite = true)
|
|
|
- {
|
|
|
- if (overwrite) File.Delete(targetFilePath);
|
|
|
- using (ResourceWriter rw = new ResourceWriter(targetFilePath))
|
|
|
- {
|
|
|
- foreach (KeyValuePair<string, object> pair in objCollection)
|
|
|
- //为了防传进来的资源名有数字开头,资源名都加了前缀_
|
|
|
- rw.AddResource("_" + pair.Key, pair.Value);
|
|
|
- rw.Generate();
|
|
|
- rw.Close();
|
|
|
- }
|
|
|
- }
|
|
|
- /// <summary>
|
|
|
- /// 解包资源文件,返回所有资源及其资源名
|
|
|
- /// </summary>
|
|
|
- /// <param name="targetFilePath">要解包的资源文件。默认为当前目录下的"MyRes.pck"</param>
|
|
|
- /// <returns>资源字典,键值为资源唯一标示名。若无资源返回空集合。</returns>
|
|
|
- public static Dictionary<string, object> ResourceUnpack(string targetFilePath)
|
|
|
- {
|
|
|
- Dictionary<string, object> rtn = new Dictionary<string, object>();
|
|
|
- using (ResourceReader rr = new ResourceReader(targetFilePath))
|
|
|
- {
|
|
|
- foreach (DictionaryEntry entry in rr)
|
|
|
- rtn.Add(((string)entry.Key).Substring(1), entry.Value);
|
|
|
- }
|
|
|
- return rtn;
|
|
|
- }
|
|
|
- /// <summary>
|
|
|
- /// 根据资源名在指定的资源文件中检索资源
|
|
|
- /// </summary>
|
|
|
- /// <param name="resName">资源名</param>
|
|
|
- /// <param name="targetFilePath">要在其中检索的资源文件名,默认为"MyRes.pck"</param>
|
|
|
- /// <returns>资源名对应的资源</returns>
|
|
|
- public static object ResourceSearch(string resName, string targetFilePath)
|
|
|
- {
|
|
|
- object rtn = null;
|
|
|
- using (ResourceReader rr = new ResourceReader(targetFilePath))
|
|
|
- {
|
|
|
- foreach (DictionaryEntry entry in rr)
|
|
|
- if ((string)entry.Key == '_' + resName)
|
|
|
- {
|
|
|
- rtn = entry.Value;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- return rtn;
|
|
|
- }
|
|
|
- /// <summary>
|
|
|
- /// 将对象序列化
|
|
|
- /// </summary>
|
|
|
- /// <param name="FilePath">文件(支持绝大多数数据类型)</param>
|
|
|
- /// <param name="obj">要序列化的对象(如哈希表,数组等等)</param>
|
|
|
- public static void FileSerialize(string FilePath, object obj)
|
|
|
- {
|
|
|
- if (File.Exists(FilePath))
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
- FileStream fs = new FileStream(FilePath, FileMode.Create);
|
|
|
- BinaryFormatter sl = new BinaryFormatter();
|
|
|
- sl.Serialize(fs, obj);
|
|
|
- fs.Close();
|
|
|
- }
|
|
|
- catch
|
|
|
- {
|
|
|
- //序列化存储失败!
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- //您读取的文件对象不存在
|
|
|
- }
|
|
|
- }
|
|
|
- /// <summary>
|
|
|
- /// 将文件反序列化
|
|
|
- /// </summary>
|
|
|
- /// <param name="FilePath">文件路径(必须是经过当前序列化后的文件)</param>
|
|
|
- /// <returns>返回 null 表示序列反解失败或者目标文件不存在</returns>
|
|
|
- public static object FileDeSerialize(string FilePath)
|
|
|
- {
|
|
|
- if (System.IO.File.Exists(FilePath))
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
- FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
|
|
- BinaryFormatter sl = new BinaryFormatter();
|
|
|
- object obg = sl.Deserialize(fs);
|
|
|
- fs.Close();
|
|
|
- return obg;
|
|
|
- }
|
|
|
- catch
|
|
|
- {
|
|
|
- return null;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- return null;
|
|
|
- }
|
|
|
- }
|
|
|
- #endregion
|
|
|
-
|
|
|
/// <summary>
|
|
|
/// 打包
|
|
|
/// </summary>
|
|
|
@@ -159,42 +50,44 @@ namespace Y.Utils.IOUtils.FileUtils
|
|
|
long allfilesize = files.Sum(x => x.Size);
|
|
|
using (FileStream fsWrite = new FileStream(dstFile, FileMode.Create))
|
|
|
{
|
|
|
- //写入文件类型标识和版本号
|
|
|
- byte[] filetypeandversion = Encoding.Default.GetBytes(FileType + FileVersion);
|
|
|
- fsWrite.Write(filetypeandversion, 0, filetypeandversion.Length);
|
|
|
-
|
|
|
- //写入头部总长度
|
|
|
- int headl = files.Sum(x => x.AllByteLength);
|
|
|
- byte[] headlength = BitConverter.GetBytes(headl);
|
|
|
- fsWrite.Write(headlength, 0, headlength.Length);
|
|
|
- //循环写入文件信息
|
|
|
- files.ForEach(x =>
|
|
|
- {
|
|
|
- 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 =>
|
|
|
+ try
|
|
|
{
|
|
|
- using (FileStream fsRead = new FileStream(DirTool.Combine(srcPath, x.Path, x.Name), FileMode.Open))
|
|
|
+ //写入文件类型标识和版本号
|
|
|
+ byte[] filetypeandversion = Encoding.Default.GetBytes(FileType + FileVersion);
|
|
|
+ fsWrite.Write(filetypeandversion, 0, filetypeandversion.Length);
|
|
|
+
|
|
|
+ //写入头部总长度
|
|
|
+ int headl = files.Sum(x => x.AllByteLength);
|
|
|
+ byte[] headlength = BitConverter.GetBytes(headl);
|
|
|
+ fsWrite.Write(headlength, 0, headlength.Length);
|
|
|
+ //循环写入文件信息
|
|
|
+ files.ForEach(x =>
|
|
|
{
|
|
|
- int readCount = 0;
|
|
|
- byte[] buffer = new byte[FileBuffer];
|
|
|
- while ((readCount = fsRead.Read(buffer, 0, buffer.Length)) > 0)
|
|
|
+ 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(srcPath, x.Path, x.Name), FileMode.Open))
|
|
|
{
|
|
|
- fsWrite.Write(buffer, 0, readCount);
|
|
|
- allfilesize -= readCount;
|
|
|
+ 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();
|
|
|
+ });
|
|
|
+ }
|
|
|
+ catch (Exception e) { }
|
|
|
}
|
|
|
if (allfilesize == 0)
|
|
|
{
|
|
|
@@ -212,7 +105,12 @@ namespace Y.Utils.IOUtils.FileUtils
|
|
|
/// <summary>
|
|
|
/// 解包
|
|
|
/// </summary>
|
|
|
- /// <returns></returns>
|
|
|
+ /// <returns>
|
|
|
+ /// -11; //要解包的文件不存在
|
|
|
+ /// -12;//要解包的目标文件夹已存在
|
|
|
+ /// -20;// 文件类型不匹配
|
|
|
+ /// -404;//未知错误,操作失败
|
|
|
+ /// </returns>
|
|
|
public static int Unpack(string srcFile, string dstPath, bool overwrite = true)
|
|
|
{
|
|
|
DateTime beginTime = DateTime.Now;
|
|
|
@@ -221,54 +119,68 @@ namespace Y.Utils.IOUtils.FileUtils
|
|
|
|
|
|
using (FileStream fsRead = new FileStream(srcFile, FileMode.Open))
|
|
|
{
|
|
|
- string version = GetFileVersion(fsRead);
|
|
|
- if (version == null) return -20;// 文件类型不匹配
|
|
|
-
|
|
|
- //读取头部总长度
|
|
|
- byte[] headl = new byte[4];
|
|
|
- int headlength = 0;
|
|
|
- fsRead.Read(headl, 0, headl.Length);
|
|
|
- headlength = BitConverter.ToInt32(headl, 0);
|
|
|
- if (headlength > 0)
|
|
|
+ try
|
|
|
{
|
|
|
- //读取文件列表信息
|
|
|
- byte[] headdata = new byte[headlength];
|
|
|
- fsRead.Read(headdata, 0, headlength);
|
|
|
- List<FilePackageModel> files = GetFilePackageModel(headdata);
|
|
|
- if (ListTool.HasElements(files))
|
|
|
+ string version = GetFileVersion(fsRead);
|
|
|
+ if (version == null) return -20;// 文件类型不匹配
|
|
|
+
|
|
|
+ //读取头部总长度
|
|
|
+ byte[] headl = new byte[4];
|
|
|
+ int headlength = 0;
|
|
|
+ fsRead.Read(headl, 0, headl.Length);
|
|
|
+ headlength = BitConverter.ToInt32(headl, 0);
|
|
|
+ if (headlength > 0)
|
|
|
{
|
|
|
- files.ForEach(x =>
|
|
|
+ //读取文件列表信息
|
|
|
+ byte[] headdata = new byte[headlength];
|
|
|
+ fsRead.Read(headdata, 0, headlength);
|
|
|
+ List<FilePackageModel> files = GetFilePackageModel(headdata);
|
|
|
+ if (ListTool.HasElements(files))
|
|
|
{
|
|
|
- if (DirTool.Create(DirTool.Combine(dstPath, x.Path)))
|
|
|
+ //读取写出所有文件
|
|
|
+ files.ForEach(x =>
|
|
|
{
|
|
|
- using (FileStream fsWrite = new FileStream(DirTool.Combine(dstPath, x.Path, x.Name), FileMode.Create))
|
|
|
+ if (DirTool.Create(DirTool.Combine(dstPath, x.Path)))
|
|
|
{
|
|
|
- long size = x.Size;
|
|
|
- int readCount = 0;
|
|
|
- byte[] buffer = new byte[FileBuffer];
|
|
|
-
|
|
|
- while (size > FileBuffer)
|
|
|
- {
|
|
|
- readCount = fsRead.Read(buffer, 0, buffer.Length);
|
|
|
- fsWrite.Write(buffer, 0, readCount);
|
|
|
- size -= readCount;
|
|
|
- }
|
|
|
- if (size <= FileBuffer)
|
|
|
+ using (FileStream fsWrite = new FileStream(DirTool.Combine(dstPath, x.Path, x.Name), FileMode.Create))
|
|
|
{
|
|
|
- readCount = fsRead.Read(buffer, 0, (int)size);
|
|
|
- fsWrite.Write(buffer, 0, readCount);
|
|
|
+ long size = x.Size;
|
|
|
+ int readCount = 0;
|
|
|
+ byte[] buffer = new byte[FileBuffer];
|
|
|
+
|
|
|
+ while (size > FileBuffer)
|
|
|
+ {
|
|
|
+ readCount = fsRead.Read(buffer, 0, buffer.Length);
|
|
|
+ fsWrite.Write(buffer, 0, readCount);
|
|
|
+ size -= readCount;
|
|
|
+ }
|
|
|
+ if (size <= FileBuffer)
|
|
|
+ {
|
|
|
+ readCount = fsRead.Read(buffer, 0, (int)size);
|
|
|
+ fsWrite.Write(buffer, 0, readCount);
|
|
|
+ }
|
|
|
}
|
|
|
- fsWrite.Close();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ //验证文件列表
|
|
|
+ bool allCheck = true;
|
|
|
+ foreach (var file in files)
|
|
|
+ {
|
|
|
+ string temp = DirTool.Combine(dstPath, file.Path, file.Name);
|
|
|
+ string tempMD5 = FileTool.GetMD5(temp);
|
|
|
+ if (tempMD5 != file.MD5)//验证文件MD5不匹配则跳出验证
|
|
|
+ {
|
|
|
+ allCheck = false;
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
- });
|
|
|
+ if (allCheck) return (int)Math.Ceiling((DateTime.Now - beginTime).TotalSeconds);//操作成功
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- int a = 111;
|
|
|
}
|
|
|
- fsRead.Close();
|
|
|
+ catch (Exception e) { }
|
|
|
}
|
|
|
- return (int)Math.Ceiling((DateTime.Now - beginTime).TotalSeconds);//操作成功
|
|
|
+ return -404;//未知错误,操作失败
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -281,18 +193,21 @@ namespace Y.Utils.IOUtils.FileUtils
|
|
|
private static string GetFileVersion(FileStream fs)
|
|
|
{
|
|
|
string result = null;
|
|
|
- //读取文件类型标识和版本号
|
|
|
- byte[] filetype = Encoding.Default.GetBytes(FileType);
|
|
|
- fs.Read(filetype, 0, filetype.Length);
|
|
|
- string filetypestr = Encoding.Default.GetString(filetype);
|
|
|
-
|
|
|
- byte[] fileversion = Encoding.Default.GetBytes(FileVersion);
|
|
|
- fs.Read(fileversion, 0, fileversion.Length);
|
|
|
- string fileversionstr = Encoding.Default.GetString(fileversion);
|
|
|
+ try
|
|
|
+ {
|
|
|
+ //读取文件类型标识和版本号
|
|
|
+ byte[] filetype = Encoding.Default.GetBytes(FileType);
|
|
|
+ fs.Read(filetype, 0, filetype.Length);
|
|
|
+ string filetypestr = Encoding.Default.GetString(filetype);
|
|
|
|
|
|
- //如果文件类型匹配,则返回版本号
|
|
|
- if (filetypestr == FileType) result = fileversionstr;
|
|
|
+ byte[] fileversion = Encoding.Default.GetBytes(FileVersion);
|
|
|
+ fs.Read(fileversion, 0, fileversion.Length);
|
|
|
+ string fileversionstr = Encoding.Default.GetString(fileversion);
|
|
|
|
|
|
+ //如果文件类型匹配,则返回版本号
|
|
|
+ if (filetypestr == FileType) result = fileversionstr;
|
|
|
+ }
|
|
|
+ catch (Exception e) { }
|
|
|
return result;
|
|
|
}
|
|
|
/// <summary>
|