// 将源文件中指定的片断内容复制到目标文件中 // 当strContentRange的值为""时,表示复制整个文件 // 返回值:-1 出错 其他 复制的总尺寸 public static long CopyFragment( string strSourceFileName, string strContentRange, string strTargetFileName, out string strErrorInfo) { long lTotalBytes = 0; strErrorInfo = ""; FileInfo fi = new FileInfo(strSourceFileName); if (fi.Length == 0) { return(0); } // 表示范围的字符串为空,恰恰表示要包含全部范围 if (strContentRange == "") { strContentRange = "0-" + Convert.ToString(fi.Length - 1); } // 创建RangeList,便于理解范围字符串 RangeList rl = new RangeList(strContentRange); // 检查strContentRange指出的最大最小边界和源文件中实际情况是否矛盾 long lMax = rl.max(); if (fi.Length <= lMax) { strErrorInfo = "文件" + strSourceFileName + "文件尺寸比范围" + strContentRange + "中定义的最大边界" + Convert.ToString(lMax) + "小..."; return(-1); } long lMin = rl.min(); if (fi.Length <= lMin) { strErrorInfo = "文件" + strSourceFileName + "文件尺寸比范围" + strContentRange + "中定义的最小边界" + Convert.ToString(lMax) + "小..."; return(-1); } using (FileStream fileTarget = File.Create(strTargetFileName)) using (FileStream fileSource = File.Open(strSourceFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { // 循环,复制每个连续片断 for (int i = 0; i < rl.Count; i++) { RangeItem ri = (RangeItem)rl[i]; fileSource.Seek(ri.lStart, SeekOrigin.Begin); DumpStream(fileSource, fileTarget, ri.lLength, true); lTotalBytes += ri.lLength; } } return(lTotalBytes); }
// 注意,本函数会改变文件当前指针位置,算法有缺陷 // 将源文件中指定的片断内容复制到目标文件中 // 当strContentRange的值为""时,表示复制整个文件 // parameters: // lFileStart fileSource 中打算操作的片段的起始位置。strContentRange 中的数字,是从这个起始位置以后计算的 // 返回值:-1 出错 其他 复制的总尺寸 public static long CopyFragment( Stream fileSource, long lTotalLength, string strContentRange, long lFileStart, out byte[] baResult, out string strErrorInfo) { long lTotalBytes = 0; strErrorInfo = ""; baResult = null; /* * FileInfo fi = new FileInfo(strSourceFileName); * if (fi.Length == 0) * return 0; */ // long lFileStart = fileSource.Position; // 表示范围的字符串为空,恰恰表示要包含全部范围 if (strContentRange == "") { if (lTotalLength == 0) // 2005/6/24 { baResult = new byte[0]; return(0); } strContentRange = "0-" + Convert.ToString(lTotalLength - 1); } // 创建RangeList,便于理解范围字符串 RangeList rl = new RangeList(strContentRange); // 检查strContentRange指出的最大最小边界和源文件中实际情况是否矛盾 long lMax = rl.max(); if (lTotalLength <= lMax) { strErrorInfo = "文件尺寸比范围" + strContentRange + "中定义的最大边界" + Convert.ToString(lMax) + "小..."; return(-1); } long lMin = rl.min(); if (lTotalLength <= lMin) { strErrorInfo = "文件尺寸比范围" + strContentRange + "中定义的最小边界" + Convert.ToString(lMax) + "小..."; return(-1); } /* * FileStream fileSource = File.Open( * strSourceFileName, * FileMode.Open, * FileAccess.Read, * FileShare.ReadWrite); */ // int nStart = 0; // 循环,复制每个连续片断 for (int i = 0, nStart = 0; i < rl.Count; i++) { RangeItem ri = (RangeItem)rl[i]; // TODO: 这里是性能瓶颈。应该是 SeekOrigin.Current 才好 // fileSource.Seek(ri.lStart + lFileStart, SeekOrigin.Begin); FastSeek(fileSource, ri.lStart + lFileStart); baResult = ByteArray.EnsureSize(baResult, nStart + (int)ri.lLength); nStart += fileSource.Read(baResult, nStart, (int)ri.lLength); lTotalBytes += ri.lLength; } // fileSource.Close(); return(lTotalBytes); }
// 2017/9/16 修改后版本 // 将源文件中指定的片断内容复制到目标文件中 // 当strContentRange的值为""时,表示复制整个文件 // 返回值:-1 出错 其他 复制的总尺寸 public static long CopyFragmentNew( Stream fileSource, long lTotalLength, string strContentRange, out byte[] baResult, out string strErrorInfo) { long lTotalBytes = 0; strErrorInfo = ""; baResult = null; // long lFileStart = fileSource.Position; // 表示范围的字符串为空,恰恰表示要包含全部范围 if (string.IsNullOrEmpty(strContentRange) == true) { if (lTotalLength == 0) { baResult = new byte[0]; return(0); } strContentRange = "0-" + Convert.ToString(lTotalLength - 1); } // 创建 RangeList,便于理解范围字符串 RangeList rl = new RangeList(strContentRange); // 检查 strContentRange 指出的最大最小边界和源文件中实际情况是否矛盾 long lMax = rl.max(); if (lTotalLength <= lMax) { strErrorInfo = "文件尺寸比范围" + strContentRange + "中定义的最大边界" + Convert.ToString(lMax) + "小..."; return(-1); } long lMin = rl.min(); if (lTotalLength <= lMin) { strErrorInfo = "文件尺寸比范围" + strContentRange + "中定义的最小边界" + Convert.ToString(lMax) + "小..."; return(-1); } // 循环,复制每个连续片断 for (int i = 0, nStart = 0; i < rl.Count; i++) { RangeItem ri = (RangeItem)rl[i]; FastSeek(fileSource, ri.lStart); baResult = ByteArray.EnsureSize(baResult, nStart + (int)ri.lLength); nStart += fileSource.Read(baResult, nStart, (int)ri.lLength); lTotalBytes += ri.lLength; } return(lTotalBytes); }