// public List<int> GetBreakPoint(FileNode fileNode) // { // if (String.IsNullOrEmpty(fileNode.SnapPath)) // { // throw new Exception("The snapshot path of file is empty."); // } // FileStream fileStream = null; // try // { // fileStream = new FileStream(fileNode.SnapPath, FileMode.Open); // var buffer = new byte[1]; // for (; fileStream.Read(buffer, 0, 1) > 0; p++) // { // window.Add(buffer[0]); // int hash = window.GetHashCode(); // if (p - l < CommonConstants.MinChunkSize) // { // continue; // } // if ((hash % dDash) == (dDash - 1)) // { // logger.Debug("========HIT!!!!!!!------------(hash % dDash) == (dDash - 1)"); // backupBreak = p; // } // if ((hash % d) == (d - 1)) // { // logger.Debug("========HIT!!!!!!!------------Hash%d==d - 1"); // breakPoint.Add(p); // window.Clear(); // backupBreak = 0; // l = p; // continue; // } // if (p - l < CommonConstants.MaxChunkSize) // { // continue; // } // if (backupBreak != 0) // { // breakPoint.Add(backupBreak); // window.Clear(); // l = backupBreak; // backupBreak = 0; // } // else // { // logger.Debug("========MAX"); // breakPoint.Add(p); // window.Clear(); // l = p; // backupBreak = 0; // } // } // fileStream.Close(); // return breakPoint; // } // catch (Exception e) // { // logger.Debug("Failed to get the break point of file, details: {0}.", e); // return null; // } // finally // { // if (fileStream != null) // { // fileStream.Close(); // fileStream = null; // } // } // } public void GetChunkByTTTD(FileNode fileNode) { logger.Debug("FileName: {0}.", fileNode.SnapPath); ChunkInfo chunk = chunkQueue.TakeFreeBlock(); chunk.FileId = fileNode.Id; if (String.IsNullOrEmpty(fileNode.SnapPath)) { throw new Exception("The snapshot path of file is empty."); } FileStream fileStream = null; try { fileStream = GetFileStream(fileNode.SnapPath); var buffer = new byte[1]; var offset = 0; p = 0; UInt64 hash = 0; for (; fileStream.Read(buffer, 0, 1) > 0; p++, offset++) { chunk.Buffer[offset] = buffer[0]; if (p - l < Constants.MinChunkSize) { continue; } hash = RabinHash.GetRabinHash(chunk.Buffer); /*RabinFingerPrint.ComputeFingerPrint(chunk.Buffer)*/; //Logger.Debug("RabinFingerprint: {0}.", hash); //get the alternative break point if ((hash % DAlternative) == (DAlternative - 1)) { //Logger.Debug("Set break point when remainder is (DAlternative - 1), chunk length: {0}, fingerprint: {1}.", offset, hash); backupBreak = p; } if ((hash % D) == (D - 1)) { //Logger.Debug("Set break point when remainder is (D - 1), chunk length: {0}, fingerprint: {1}.", offset, hash); chunk.BufferLength = offset + 1; CalculateCheckSumAndInQueue(chunk); //breakPoint.Add(p); chunk = chunkQueue.TakeFreeBlock(); chunk.FileId = fileNode.Id; offset = -1; backupBreak = 0; l = p; continue; } if (p - l < Constants.MaxChunkSize) { continue; } if (backupBreak != 0) { chunk.BufferLength = offset + 1; CalculateCheckSumAndInQueue(chunk); //breakPoint.Add(backupBreak); chunk = chunkQueue.TakeFreeBlock(); chunk.FileId = fileNode.Id; offset = -1; l = backupBreak; backupBreak = 0; } else { //Logger.Debug("Set break point at max length of chunk, chunk length: {0}, fingerprint: {1}.", offset + 1, hash); chunk.BufferLength = offset + 1; CalculateCheckSumAndInQueue(chunk); offset = -1; //breakPoint.Add(p); chunk = chunkQueue.TakeFreeBlock(); chunk.FileId = fileNode.Id; l = p; backupBreak = 0; } } hash = RabinHash.GetRabinHash(chunk.Buffer); //logger.Debug("Set break point at the end of a file, chunk length: {0}, fingerprint: {1}.", offset + 1, hash); chunk.BufferLength = offset + 1; CalculateCheckSumAndInQueue(chunk); fileStream.Close(); } catch (Exception e) { logger.Debug("Failed to get the break point of file, details: {0}.", e); } finally { if (fileStream != null) { fileStream.Close(); fileStream = null; } } }
public void GetChunkWithoutTTTD(FileNode fileNode) { ChunkInfo chunk = chunkQueue.TakeFreeBlock(); chunk.FileId = fileNode.Id; if (String.IsNullOrEmpty(fileNode.SnapPath)) { throw new Exception("The snapshot path of file is empty."); } FileStream fileStream = null; try { fileStream = GetFileStream(fileNode.SnapPath); logger.Debug("File name: {0}, size: {1}.", fileNode.SnapPath, fileStream.Length); p = 0; while (true) { int length = fileStream.Read(chunk.Buffer, 0, Constants.MaxChunkSize); if (length <= 0) { break; } chunk.BufferLength = length; CalculateCheckSumAndInQueue(chunk); //logger.Debug("Id: {0}, length: {1}.", chunk.Id, chunk.BufferLength); chunk = chunkQueue.TakeFreeBlock(); chunk.FileId = fileNode.Id; } chunkQueue.PutFreeBlock(chunk); } catch (Exception e) { logger.Debug("Failed to get the break point of file, details: {0}.", e); } finally { if (fileStream != null) { fileStream.Close(); fileStream = null; } } }
/// <summary> /// 服务器文件列表与本地对比,逻辑如下: /// 1.如果服务器存在,本地不存在: /// 1.1) 如果文件状态为Deleted,跳过 /// 1.2) 否则,下载 /// 2.如果本地存在,服务器不存在,则上传 /// 3.如果都存在,比较更新时间: /// 3.1) 如果本地较新,则上传,并置文件状态为Modified /// 3.2) 如果服务器较新: /// 3.2.1) 如果文件状态为Deleted,则删除本地文件 /// 3.2.2) 否则,下载文件 /// </summary> /// <param name="path"></param> /// <param name="parentFolder"></param> private void BrowseAndUpdateTree(String path, String parentFolder) { try { var dirInfo = new DirectoryInfo(path); var localFileList = dirInfo.GetFiles(); foreach (var file in localFileList) { var localFile = new FileNode { Id = Guid.NewGuid().ToStringEx(), RelativePath = parentFolder, Name = file.Name, Length = file.Length, UpdateTime = file.LastWriteTimeUtc.Ticks, Status = FileStatus.Added }; var serverFile = serverTree.FileList.FirstOrDefault(item => item.Name.Equals(file.Name)); if (serverFile == null) //condition 2 { logger.Debug("Added upload, {0}.", localFile.Name); uploadFileList.Add(localFile); serverTree.FileList.Add(localFile); } else //condition 3 { if (serverFile.UpdateTime > localFile.UpdateTime) //condition 3.2 { if (serverFile.Status == FileStatus.Deleted) //condition 3.2.1 { logger.Debug("Deleted, {0}.", localFile.Name); File.Delete(file.FullName); } else //condition 3.2.2 { logger.Debug("Added download, {0}.", localFile.Name); downloadFileList.Add(serverFile); } } else //condition 3.1 { logger.Debug("Add upload, {0}.", localFile.Name); serverFile.UpdateTime = localFile.UpdateTime; serverFile.Status = FileStatus.Modified; uploadFileList.Add(localFile); } } } foreach (var serverFile in serverTree.FileList) { var localFile = localFileList.FirstOrDefault(item => item.Name.Equals(serverFile.Name)); if (localFile == null && serverFile.Status != FileStatus.Deleted) //condition 1.2 { logger.Debug("Added download, {0}.", serverFile.Name); downloadFileList.Add(serverFile); } } dirInfo.GetDirectories().ForEach(item => BrowseAndUpdateTree(item.DirectoryName, parentFolder + "\\" + item.Name)); } catch (Exception e) { logger.Debug("Error occurred when browsing folder, info: {0}.", e); } }