Пример #1
0
        public static Dictionary <string, FileDetailInfo> StringToFileList(string content, out FileListParseError error)
        {
            error = FileListParseError.Null;
            Dictionary <string, FileDetailInfo> retList = new Dictionary <string, FileDetailInfo> ();

            string[] detailInfos = content.Split(DetailSeparator);
            //因为在序列化时,每一条信息后边都追加了一个DetailSeparator,所以detailInfos数组最后一条回事null
            for (int i = 0; i < detailInfos.Length - 1; ++i)
            {
                if (string.IsNullOrEmpty(detailInfos [i]))
                {
                    error = FileListParseError.DetailInfoIsNull;
                    return(null);
                }
                FileDetailInfo info = StringToFileDetailInfo(detailInfos [i], out error);
                if (null == info)
                {
                    return(null);
                }
                if (retList.ContainsKey(info.fileName))
                {
                    error = FileListParseError.FileRepeat;
                    return(null);
                }
                retList.Add(info.fileName, info);
            }
            return(retList);
        }
Пример #2
0
 private static void AppendDetailInfo(StringBuilder sb, FileDetailInfo info)
 {
     sb.Append(info.fileName + VariableSeparator);
     sb.Append(info.filePath + VariableSeparator);
     sb.Append(info.fileMd5 + VariableSeparator);
     sb.Append(info.fileLength);
 }
Пример #3
0
        public static string DetailInfoToString(FileDetailInfo detailInfo)
        {
            StringBuilder sb = new StringBuilder();

            AppendDetailInfo(sb, detailInfo);
            sb.Append(DetailSeparator);
            return(sb.ToString());
        }
Пример #4
0
    private static void SeachDirectoryFIles(Dictionary <string, NewFileSystem.FileDetailInfo> fileListDic, DirectoryInfo directoryInfo, string relativePath, string targetPath, bool isServerBuild)
    {
        FileInfo[] fileInfos = directoryInfo.GetFiles();
        if (isServerBuild && !Directory.Exists(targetPath))
        {
            Directory.CreateDirectory(targetPath);
        }
        for (int i = 0; i < fileInfos.Length; ++i)
        {
            NewFileSystem.FileDetailInfo detailInfo = new NewFileSystem.FileDetailInfo();
            FileInfo fileInfo = fileInfos [i];
            if (fileInfo.Name == ".DS_Store")
            {
                continue;
            }
            if (fileInfo.Extension == ".meta")
            {
                continue;
            }
            if (fileInfo.Length == 0)
            {
                Debug.LogError("Find file size is zero " + fileInfo.FullName);
                continue;
            }
            byte[] fileContent = File.ReadAllBytes(fileInfo.FullName);
            detailInfo.fileMd5    = Utils.MD5(fileContent);
            detailInfo.fileName   = fileInfo.Name;
            detailInfo.fileLength = fileInfo.Length;
            detailInfo.filePath   = relativePath;
            if (fileListDic.ContainsKey(detailInfo.fileName))
            {
                Debug.LogError("Has same name file " + fileInfo.FullName);
            }
            else
            {
                fileListDic.Add(detailInfo.fileName, detailInfo);
            }

            if (isServerBuild)
            {
                string targetFilePath = Path.Combine(targetPath, detailInfo.fileMd5);
                if (File.Exists(targetFilePath))
                {
                    File.Delete(targetFilePath);
                }
                File.Copy(fileInfo.FullName, targetFilePath);
            }
        }

        DirectoryInfo[] directoryInfos = directoryInfo.GetDirectories();
        for (int i = 0; i < directoryInfos.Length; ++i)
        {
            SeachDirectoryFIles(fileListDic, directoryInfos [i]
                                , Path.Combine(relativePath, directoryInfos [i].Name)
                                , Path.Combine(targetPath, directoryInfos [i].Name)
                                , isServerBuild);
        }
    }
Пример #5
0
        public static string FileListToString(Dictionary <string, FileDetailInfo> fileListDic)
        {
            StringBuilder sb         = new StringBuilder();
            var           enumerator = fileListDic.GetEnumerator();

            while (enumerator.MoveNext())
            {
                FileDetailInfo detailInfo = enumerator.Current.Value;
                AppendDetailInfo(sb, detailInfo);
                sb.Append(DetailSeparator);
            }
            return(sb.ToString());
        }
Пример #6
0
        private void GetUpdatedFile()
        {
            mSynchronizeData.needDownloadSet = new List <FileDetailInfo> ();
            var enumerator = mSynchronizeData.serverFileListDic.GetEnumerator();

            while (enumerator.MoveNext())
            {
                FileDetailInfo serverDetailInfo = enumerator.Current.Value;
                FileDetailInfo localDetailInfo  = null;
                if (!mSynchronizeData.persistentFileListDic.TryGetValue(serverDetailInfo.fileName, out localDetailInfo))
                {
                    FileDetailInfo streamingDetailInfo;
                    if (null != mSynchronizeData.streamingFileListDic && mSynchronizeData.streamingFileListDic.TryGetValue(serverDetailInfo.fileName, out streamingDetailInfo))
                    {
                        if (streamingDetailInfo.fileMd5 != serverDetailInfo.fileMd5 || streamingDetailInfo.filePath != serverDetailInfo.filePath)
                        {
                            mSynchronizeData.needDownloadSet.Add(serverDetailInfo);
                        }
                        else
                        {
                            //在StreamingAssets目录下存在相同的文件,不需要下载
                        }
                    }
                    else
                    {
                        mSynchronizeData.needDownloadSet.Add(serverDetailInfo);
                    }
                    continue;
                }
                if (localDetailInfo.fileMd5 != serverDetailInfo.fileMd5)
                {
                    mSynchronizeData.needDownloadSet.Add(serverDetailInfo);
                    string localFilePath = FileSystemUtils.GetFileRelativePath(localDetailInfo.fileName, localDetailInfo.filePath, true);
                    GameMain.Instance.FileOperateMgr.DeleteIfExist(localFilePath);
                    mSynchronizeData.persistentFileListDic.Remove(localDetailInfo.fileName);
                    mLocalFileListHasChange = true;
                    continue;
                }
                if (localDetailInfo.filePath != serverDetailInfo.filePath)
                {
                    string fromLocalFilePath = FileSystemUtils.GetFileRelativePath(localDetailInfo.fileName, localDetailInfo.filePath, true);
                    string toLocalFilePath   = FileSystemUtils.GetFileRelativePath(serverDetailInfo.fileName, serverDetailInfo.filePath, true);
                    GameMain.Instance.FileOperateMgr.MoveFile(fromLocalFilePath, toLocalFilePath);
                    localDetailInfo.filePath = serverDetailInfo.filePath;
                    mLocalFileListHasChange  = true;
                }
            }
        }
        private void CheckDiskFile(DirectoryInfo directoryInfo, string relativePath)
        {
            FileInfo[] fileInfos = directoryInfo.GetFiles();
            for (int i = 0; i < fileInfos.Length; ++i)
            {
                FileInfo       fileInfo   = fileInfos [i];
                string         fileName   = fileInfo.Name;
                bool           needRemove = false;
                FileDetailInfo info       = null;
                if (mSynchronizeData.persistentFileListDic.TryGetValue(fileName, out info))
                {
                    //文件列表中存在,需要判断路径是否一致
                    if (relativePath != info.filePath)
                    {
                        //路径不一致,需要删除文件
                        needRemove = true;
                    }
                    else
                    {
                        //路径一致时,在文件列表到硬盘的检查中已经覆盖,不需要处理
                    }
                }
                else
                {
                    //文件列表中不存在
                    needRemove = true;
                }
                if (needRemove)
                {
                    string fileRelativePath = FileSystemUtils.GetFileRelativePath(fileName, relativePath, true);
                    GameMain.Instance.FileOperateMgr.DeleteIfExist(fileRelativePath);
                    mSynchronizeData.persistentFileListDic.Remove(fileName);
                    mSynchronizeData.localVersionInfo.Clear();
                }
            }

            DirectoryInfo[] childDirectories = directoryInfo.GetDirectories();
            for (int i = 0; i < childDirectories.Length; ++i)
            {
                DirectoryInfo childDirectory = childDirectories [i];
                CheckDiskFile(childDirectory, Path.Combine(relativePath, childDirectory.Name));
            }
            if (directoryInfo.GetFiles().Length == 0 && directoryInfo.GetDirectories().Length == 0)
            {
                directoryInfo.Delete();
            }
        }
Пример #8
0
        private void GenerateCopyList()
        {
            bool hasPersistentListChanged = false;

            Dictionary <string, FileDetailInfo> .Enumerator enumerateo = mStreamingFileListDic.GetEnumerator();
            while (enumerateo.MoveNext())
            {
                string         fileName             = enumerateo.Current.Key;
                FileDetailInfo streamDetailInfo     = enumerateo.Current.Value;
                FileDetailInfo persistentDetailInfo = null;

                if (null == mPersistentFileListDic || !mPersistentFileListDic.TryGetValue(fileName, out persistentDetailInfo))
                {
                    mCopyList.Add(fileName);
                }
                else
                {
                    if (persistentDetailInfo.fileMd5 != streamDetailInfo.fileMd5 || persistentDetailInfo.filePath != streamDetailInfo.filePath)
                    {
                        string relativePath = FileSystemUtils.GetFileRelativePath(fileName, persistentDetailInfo.filePath, true);
                        GameMain.Instance.FileOperateMgr.DeleteIfExist(relativePath);
                        mCopyList.Add(fileName);
                        hasPersistentListChanged = true;
                        mPersistentFileListDic.Remove(fileName);
                    }
                }
            }

            if (hasPersistentListChanged)
            {
                //使Persistent目录下的文件列表和实际文件一致,避免下一阶段拷贝中断造成文件列表和实际文件不一致
                string        errorStr;
                FileErrorCode errorCode = FileListUtils.WriteFileList(mPersistentFileListDic, out errorStr);
                if (FileErrorCode.Null != errorCode)
                {
                    OnError("GenerateCopyList write persistent fileList " + errorCode.ToString() + " " + errorStr);
                    return;
                }
            }
            mCopyFileMaxCount = mCopyList.Count;
            CopyFiles();
        }
Пример #9
0
        private void CopyFiles()
        {
            Lancher.Instance.SetTips("请稍等,正在解压资源......(" + (mCopyFileMaxCount - mCopyList.Count).ToString() + "/" + mCopyFileMaxCount + ")");
            if (mCopyList.Count == 0)
            {
                mHdlOnFinish.Invoke();
                return;
            }
            string fileName = mCopyList[mCopyList.Count - 1];

            mCopyList.RemoveAt(mCopyList.Count - 1);
            FileDetailInfo fileInfo     = mStreamingFileListDic [fileName];
            string         relativePath = FileSystemUtils.GetFileRelativePath(fileName, fileInfo.filePath, true);

            this.StartCoroutine(LoadFile(relativePath, delegate(byte[] fileBytes) {
                GameMain.Instance.FileOperateMgr.CreateDirIfNotExist(Path.GetDirectoryName(relativePath));
                string fileOpeErrorStr;
                FileErrorCode errorCode = FileOperateUtils.TryFileWrite(delegate(){
                    Logger.LogInfo("AndroidStreamingCopy copy file " + relativePath);
                    GameMain.Instance.FileOperateMgr.WriteBinaryFile(relativePath, fileBytes);
                }, out fileOpeErrorStr);

                if (FileErrorCode.Null != errorCode)
                {
                    OnError("AndroidStreamingCopy Write " + relativePath + " " + errorCode.ToString() + " " + fileOpeErrorStr);
                    return;
                }

                errorCode = FileOperateUtils.TryFileWrite(delegate(){
                    string detailStr = FileListUtils.DetailInfoToString(fileInfo);
                    GameMain.Instance.FileOperateMgr.WriteTextFile(mPersistentFileListRelativePath, detailStr, true);
                }, out fileOpeErrorStr);
                if (FileErrorCode.Null != errorCode)
                {
                    OnError("AndroidStreamingCopy write fileList " + errorCode.ToString() + " " + fileOpeErrorStr);
                    return;
                }
                CopyFiles();
            }, delegate() {
                OnError("Load streaming FileList");
            }));
        }
Пример #10
0
        private static FileDetailInfo StringToFileDetailInfo(string content, out FileListParseError errorType)
        {
            errorType = FileListParseError.Null;
            string[] detailInfos = content.Split(VariableSeparator);
            if (detailInfos.Length != 4)
            {
                errorType = FileListParseError.DetailInfoElementCountError;
                return(null);
            }
            FileDetailInfo info = new FileDetailInfo();

            info.fileName = detailInfos[0];
            info.filePath = detailInfos[1];
            info.fileMd5  = detailInfos[2];
            if (!long.TryParse(detailInfos [3], out info.fileLength))
            {
                errorType = FileListParseError.DetailInfoLengthError;
                return(null);
            }
            return(info);
        }
        /// <summary>
        /// 保证内存中的文件列表和硬盘中的所有的真实文件一致,但是可能会和硬盘中的文件列表不一致
        /// </summary>
        private void InfoCheck()
        {
            List <string> removeList = new List <string> ();

            Dictionary <string, FileDetailInfo> .Enumerator enumerator = mSynchronizeData.persistentFileListDic.GetEnumerator();
            while (enumerator.MoveNext())
            {
                FileDetailInfo detailInfo    = enumerator.Current.Value;
                string         localFilePath = FileSystemUtils.GetFileRelativePath(detailInfo.fileName, detailInfo.filePath, true);
                if (!GameMain.Instance.FileOperateMgr.IsFileExist(localFilePath))
                {
                    //也有可能只是文件在其他目录,为了逻辑简单不做文件目录的恢复功能,如果文件目录不一致,就会直接删除掉,在后面的阶段重新下载
                    removeList.Add(detailInfo.fileName);
                    continue;
                }

                long fileLength = GameMain.Instance.FileOperateMgr.GetFileLength(localFilePath);
                if (fileLength != detailInfo.fileLength)
                {
                    removeList.Add(detailInfo.fileName);
                    GameMain.Instance.FileOperateMgr.DeleteIfExist(localFilePath);
                    continue;
                }
            }

            if (removeList.Count > 0)
            {
                for (int i = 0; i < removeList.Count; ++i)
                {
                    mSynchronizeData.persistentFileListDic.Remove(removeList [i]);
                }
                mSynchronizeData.localVersionInfo.Clear();
            }

            string        relativePath  = FileSystemUtils.GetFolderRelativePath(string.Empty);
            DirectoryInfo directoryInfo = GameMain.Instance.FileOperateMgr.GetDirectoryInfo(relativePath);

            CheckDiskFile(directoryInfo, string.Empty);
        }
Пример #12
0
        private void RemoveUnusedFileList()
        {
            //找到本地存在,但是服务器中不存在的文件,在硬盘中删除
            var enumerator = mSynchronizeData.persistentFileListDic.GetEnumerator();
            List <FileDetailInfo> removeList = new List <FileDetailInfo> ();

            while (enumerator.MoveNext())
            {
                FileDetailInfo fileInfo = enumerator.Current.Value;
                if (mSynchronizeData.serverFileListDic.ContainsKey(enumerator.Current.Key))
                {
                    continue;
                }
                removeList.Add(enumerator.Current.Value);
            }
            for (int i = 0; i < removeList.Count; ++i)
            {
                FileDetailInfo removeFileInfo = removeList [i];
                string         filePath       = FileSystemUtils.GetFileRelativePath(removeFileInfo.fileName, removeFileInfo.filePath, true);
                GameMain.Instance.FileOperateMgr.DeleteIfExist(filePath);
                mSynchronizeData.persistentFileListDic.Remove(removeFileInfo.fileName);
                mLocalFileListHasChange = true;
            }
        }
        /// <summary>
        /// 加载文件列表和Version信息,并做内容合法检查
        /// </summary>
        private void LoadInfo()
        {
            string localVersionFilePath = FileSystemUtils.GetFileRelativePath(FileDownloadData.VersionFileName, string.Empty);

            if (GameMain.Instance.FileOperateMgr.IsFileExist(localVersionFilePath))
            {
                string localVersionContent = GameMain.Instance.FileOperateMgr.ReadAsText(localVersionFilePath);
                mSynchronizeData.localVersionInfo = Newtonsoft.Json.JsonConvert.DeserializeObject <LocalVersionInfo> (localVersionContent);
            }
            if (null == mSynchronizeData.localVersionInfo)
            {
                mSynchronizeData.localVersionInfo = new LocalVersionInfo();
                mSynchronizeData.localVersionInfo.Clear();
            }

            string localFileListFilePath = FileSystemUtils.GetFileRelativePath(FileDownloadData.FileListFileName, string.Empty);
            Dictionary <string, FileDetailInfo> fileListDic = null;

            if (GameMain.Instance.FileOperateMgr.IsFileExist(localFileListFilePath))
            {
                string fileListContent = GameMain.Instance.FileOperateMgr.ReadAsText(localFileListFilePath);
                FileListUtils.FileListParseError error = FileListUtils.FileListParseError.Null;
                fileListDic = FileListUtils.StringToFileList(fileListContent, out error);
                if (FileListUtils.FileListParseError.Null != error)
                {
                    //文件列表已经被破坏,所以直接删除文件
                    GameMain.Instance.FileOperateMgr.DeleteIfExist(localVersionFilePath);
                    GameMain.Instance.FileOperateMgr.DeleteIfExist(localFileListFilePath);
                }
                else
                {
                    string localFileListMd5 = Utils.MD5(fileListContent);
                    if (localFileListMd5 != mSynchronizeData.localVersionInfo.persistentMd5)
                    {
                        //文件列表被修改
                        mSynchronizeData.localVersionInfo.Clear();
                    }
                }
            }
            if (null == fileListDic)
            {
                //如果文件列表不存在,那么有可能是被其他系统删除,也有可能是文件解析失败,所以清空localVersionInfo,保证一定能够进入CompareFileListState状态
                mSynchronizeData.localVersionInfo.Clear();
                mSynchronizeData.persistentFileListDic = new Dictionary <string, FileDetailInfo> ();
            }
            else
            {
                List <string> removeList = new List <string> ();
                Dictionary <string, FileDetailInfo> .Enumerator enumerator = fileListDic.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    FileDetailInfo detailInfo = enumerator.Current.Value;
                    if (detailInfo.IsInvalid())
                    {
                        removeList.Add(enumerator.Current.Key);
                    }
                }
                if (removeList.Count > 0)
                {
                    //有部分信息是不合法的,那么一定需要进入CompareFileListState状态
                    mSynchronizeData.localVersionInfo.Clear();
                    for (int i = 0; i < removeList.Count; ++i)
                    {
                        fileListDic.Remove(removeList [i]);
                    }
                }
                mSynchronizeData.persistentFileListDic = fileListDic;
            }
        }
Пример #14
0
        private void DownLoadFile()
        {
            if (mSynchronizeData.needDownloadSet.Count == 0)
            {
                mNextHandler.Invoke(FileDownloadStateId.WritePersistentVersionFile);
                return;
            }
            ShowTipInfo();
            FileDetailInfo downloadFileInfo = mSynchronizeData.needDownloadSet [mSynchronizeData.needDownloadSet.Count - 1];

            mSynchronizeData.needDownloadSet.RemoveAt(mSynchronizeData.needDownloadSet.Count - 1);

            string fileRelativePath = null;

            if (string.IsNullOrEmpty(downloadFileInfo.filePath))
            {
                //服务器中是以MD5命名的。
                fileRelativePath = downloadFileInfo.fileMd5;
            }
            else
            {
                fileRelativePath = Path.Combine(downloadFileInfo.filePath, downloadFileInfo.fileMd5);
            }
            string fileUrl = Path.Combine(mSynchronizeData.ServerDataPath, fileRelativePath);

            mDownloadId = GameMain.Instance.HttpMgr.DownLoad(fileUrl, delegate(byte[] fileBytes) {
                Logger.LogInfo("NewDownload download file success,name:" + downloadFileInfo.fileName + " url:" + fileUrl);
                if (downloadFileInfo.fileLength != fileBytes.Length)
                {
                    mErrorHandler.Invoke(FileErrorCode.FileLengthError, fileUrl + " serverL:" + downloadFileInfo.fileLength + "  realL:" + fileBytes.Length);
                }
                else
                {
                    string md5 = Utils.MD5(fileBytes);
                    if (md5 != downloadFileInfo.fileMd5)
                    {
                        mErrorHandler.Invoke(FileErrorCode.FileMd5Error, fileUrl + " serverMd5:" + downloadFileInfo.fileMd5 + "  realMd5:" + md5);
                    }
                    else
                    {
                        string errorInfo;
                        FileErrorCode errorCode = FileOperateUtils.TryFileWrite(delegate(){
                            string relativePath = FileSystemUtils.GetFileRelativePath(downloadFileInfo.fileName, downloadFileInfo.filePath, true);
                            GameMain.Instance.FileOperateMgr.CreateDirIfNotExist(Path.GetDirectoryName(relativePath));
                            GameMain.Instance.FileOperateMgr.WriteBinaryFile(relativePath, fileBytes);
                        }, out errorInfo);
                        if (FileErrorCode.Null != errorCode)
                        {
                            mErrorHandler.Invoke(errorCode, errorInfo);
                        }
                        else
                        {
                            mSynchronizeData.persistentFileListDic.Add(downloadFileInfo.fileName, downloadFileInfo);
                            errorCode = FileOperateUtils.TryFileWrite(delegate(){
                                string detailStr    = FileListUtils.DetailInfoToString(downloadFileInfo);
                                string relativePath = FileSystemUtils.GetFileRelativePath(FileDownloadData.FileListFileName, string.Empty);
                                GameMain.Instance.FileOperateMgr.WriteTextFile(relativePath, detailStr, true);
                            }, out errorInfo);
                            if (FileErrorCode.Null != errorCode)
                            {
                                mErrorHandler.Invoke(errorCode, errorInfo);
                            }
                            else
                            {
                                mFinishFilesSize += (ulong)downloadFileInfo.fileLength;
                                mCurFileSize      = 0;
                                DownLoadFile();
                            }
                        }
                    }
                }
            }, delegate(string errorCode) {
                Logger.LogError("NewDownload download file failed,name:" + downloadFileInfo.fileName + " url:" + fileUrl);
                mErrorHandler.Invoke(FileErrorCode.DownloadFileError, fileUrl);
            }, delegate(ulong curDownloadedBytes) {
                mCurFileSize = curDownloadedBytes;
                ShowTipInfo();
            });
        }