public static string GetPathMD5(string path) { string md5; if (s_pathMD5Dic.ContainsKey(path)) { s_pathMD5Dic.TryGetValue(path, out md5); } else { md5 = MD5Util.GetMD5(path); s_pathMD5Dic.Add(path, md5); } return(md5); }
/// <summary> /// 重命名文件,加入文件MD5字符串。 /// 写入路径的长度(一字节),写入路径,以及对应的文件MD5。 /// </summary> /// <param name="filePath">File path.</param> /// <param name="replacePath">Replace path.</param> /// <param name="writer">Writer.</param> private static void RenameFileAndWriteMD5(string filePath, string replacePath, BinaryWriter writer) { string extName = Path.GetExtension(filePath); string fileName = Path.GetFileName(filePath); string fileMD5 = MD5Util.GetFileMD5(filePath); string outFileName = fileName.Replace(extName, "") + "_" + fileMD5; string outFilePath = Path.GetDirectoryName(filePath) + "/" + outFileName + extName; File.Move(filePath, outFilePath); // 重命名文件 filePath = filePath.Replace(replacePath, "").Replace(extName, ""); // 文件路径掐头去尾 writer.Write((byte)filePath.Length); // 写入路径的长度(一字节) writer.Write(filePath.ToCharArray()); // 写入路径 writer.Write(fileMD5.ToCharArray()); // 写入文件MD5 }
private static void CreateResInfo(UpdateResInfoType updateType = UpdateResInfoType.ALL) { byte[] luaBytes = null, sceneBytes = null, resBytes = null; if (updateType != UpdateResInfoType.ALL) { if (!File.Exists(resInfoFilePath)) // ResInfo 文件不存在 { updateType = UpdateResInfoType.ALL; } else { // 只用更新某部分资源信息,将资源信息分类读取出来 using (BinaryReader reader = new BinaryReader(File.Open(resInfoFilePath, FileMode.Open))) { ushort ushort1, ushort2, i; byte byte1, byte2; int sceneBytesPos, resBytesPos; // - lua bytes ushort1 = reader.ReadUInt16(); for (i = 0; i < ushort1; i++) { byte2 = reader.ReadByte(); reader.BaseStream.Position += byte2 + 16; } sceneBytesPos = (int)reader.BaseStream.Position; reader.BaseStream.Position = 0; luaBytes = reader.ReadBytes(sceneBytesPos); // - scene bytes byte1 = reader.ReadByte(); for (i = 0; i < byte1; i++) { byte2 = reader.ReadByte(); reader.BaseStream.Position += byte2 + 16; } resBytesPos = (int)reader.BaseStream.Position; reader.BaseStream.Position = sceneBytesPos; sceneBytes = reader.ReadBytes(resBytesPos - sceneBytesPos); // - res bytes ushort1 = reader.ReadUInt16(); for (i = 0; i < ushort1; i++) { byte2 = reader.ReadByte(); reader.BaseStream.Position += byte2 + 16; // 包含的资源文件 ushort2 = reader.ReadUInt16(); reader.BaseStream.Position += ushort2 * 16; // 依赖的 AssetBundle byte2 = reader.ReadByte(); reader.BaseStream.Position += byte2 * 16; } reader.BaseStream.Position = resBytesPos; resBytes = reader.ReadBytes((int)reader.BaseStream.Length - resBytesPos); } } } // 写入资源信息 using (BinaryWriter writer = new BinaryWriter(File.Open(resInfoFilePath, FileMode.Create))) { // - lua if (updateType == UpdateResInfoType.ALL || updateType == UpdateResInfoType.LUA) { writer.Write((ushort)_luaList.Count); // 写入lua文件数量 foreach (string lua in _luaList) { RenameFileAndWriteMD5(lua, luaOutputPath, writer); } } else { writer.Write(luaBytes); } // - scene if (updateType == UpdateResInfoType.ALL || updateType == UpdateResInfoType.SCENE) { writer.Write((byte)_sceneList.Count); // 写入场景文件数量(一字节) foreach (string scene in _sceneList) { RenameFileAndWriteMD5(scene, sceneOutputPath, writer); } } else { writer.Write(sceneBytes); } // - res if (updateType == UpdateResInfoType.ALL || updateType == UpdateResInfoType.RES) { // 加载 Assets/StreamingAssets/Res/Res 文件,读取包含所有ab包引用关系的 manifest AssetBundle ab = AssetBundle.LoadFromFile(resOutputPath + "Res"); AssetBundleManifest manifest = (AssetBundleManifest)ab.LoadAsset("AssetBundleManifest"); string[] abList = manifest.GetAllAssetBundles(); writer.Write((ushort)abList.Length); // 写入ab文件数量 AssetBundleInfo abi; foreach (string abPath in abList) { RenameFileAndWriteMD5(resOutputPath + abPath, resOutputPath, writer); _abiDic.TryGetValue(abPath, out abi); writer.Write((ushort)abi.assetList.Count); // 写入包含的资源文件数量 foreach (string assetPath in abi.assetList) { writer.Write(MD5Util.GetMD5(assetPath.Replace(resInputPath, "")).ToCharArray()); // 写入资源文件的路径MD5 } string[] depList = manifest.GetAllDependencies(abPath); writer.Write((byte)depList.Length); // 写入依赖的ab文件数量(一字节) foreach (string depPath in depList) { writer.Write(MD5Util.GetMD5(depPath).ToCharArray()); // 写入ab文件的路径MD5 } } ab.Unload(true); } else { writer.Write(resBytes); } } if (updateType == UpdateResInfoType.ALL) { UnityEngine.Debug.Log("[Packager] Generates ResInfo Completed."); } else { UnityEngine.Debug.Log("[Packager] Update ResInfo Completed!"); } }