// 将源文件中指定的片断内容复制到目标文件中 // 当strContentRange的值为""时,表示复制整个文件 // 返回值:-1 出错 其他 复制的总尺寸 public static long CopyFragment( Stream fileSource, long lTotalLength, string strContentRange, 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]; fileSource.Seek(ri.lStart + lFileStart, SeekOrigin.Begin); baResult = ByteArray.EnsureSize(baResult, nStart + (int)ri.lLength); nStart += fileSource.Read(baResult, nStart, (int)ri.lLength); lTotalBytes += ri.lLength; } // fileSource.Close(); return(lTotalBytes); }
// 将源文件中指定的片断内容复制到目标文件中 // 当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); }
public static void CrossOper(RangeList source1, RangeList source2, RangeList targetLeft, RangeList targetMiddle, RangeList targetRight) { int i, j; RangeItem item1 = null; // 左边队列 RangeItem item2 = null; // 右边队列 RangeItem item = null; // 临时 bool bFinished1 = false; bool bFinished2 = false; for (i = 0, j = 0; ;) { // 取队列1 if (item1 == null && bFinished1 == false && i < source1.Count) { item1 = (RangeItem)source1[i]; if (item1 == null) { throw (new ArgumentException("source1数组中位置" + Convert.ToString(i) + "(从0开始计数)包含空元素...")); } i++; } // 取队列2 if (item2 == null && bFinished2 == false && j < source2.Count) { item2 = (RangeItem)source2[j]; if (item2 == null) { throw (new ArgumentException("source2数组中位置" + Convert.ToString(j) + "(从0开始计数)包含空元素...")); } j++; } if (item1 == null && item2 == null) { break; // 全部处理完成了 } // 比较两个Item if (item1 != null && item2 != null) { // item1完全小于item2 if (item1.lStart + item1.lLength <= item2.lStart) { item = new RangeItem(item1); if (targetLeft != null) { targetLeft.Add(item); } item1 = null; // 为队列1取下一个作准备 continue; } // item2完全小于item1 if (item2.lStart + item2.lLength <= item1.lStart) { item = new RangeItem(item2); if (targetRight != null) { targetRight.Add(item); } item2 = null; // 为队列2取下一个作准备 continue; } // item1和item2部分重叠 // item1在前 if (item1.lStart <= item2.lStart) { // |item1 | // |item2 | // | A | B | C | // item1 A部分去targetLeft if (item1.lStart != item2.lStart) { item = new RangeItem(); item.lStart = item1.lStart; item.lLength = item2.lStart - item1.lStart; if (targetLeft != null) { targetLeft.Add(item); } } // item1和item2重叠的部分B,去targetMiddle item = new RangeItem(); item.lStart = item2.lStart; /* * long end1 = item1.lStart + item1.lLength; * long end2 = item2.lStart + item2.lLength; * * if (end1 <= end2) * { * item.lLength = end1 - item.lStart; * } * else * { * item.lLength = end2 - item.lStart; * } * if (targetMiddle != null) * targetMiddle.Add(item); * * // item2和Item2不重叠的C部分,留下来做下次循环 * * if (end1 <= end2) * { * if (end1 == end2) * { * item1 = null; * item2 = null; * continue; * } * item2.lStart = end1; * item2.lLength = end2 - end1; * item1 = null; * continue; * } * else * { * item1.lStart = end2; * item1.lLength = end1 - end2; * item2 = null; * continue; * } */ } // item1在前 // item2在前 else // if (item1.lStart > item2.lStart) { // |item2 | // |item1 | // | A | B | C | // item2 A部分去targetRight item = new RangeItem(); item.lStart = item2.lStart; item.lLength = item1.lStart - item2.lStart; if (targetRight != null) { targetRight.Add(item); } // item1和item2重叠的部分B,去targetMiddle item = new RangeItem(); item.lStart = item1.lStart; /* * long end1 = item1.lStart + item1.lLength; * long end2 = item2.lStart + item2.lLength; * * if (end1 <= end2) * { * item.lLength = end1 - item.lStart; * } * else * { * item.lLength = end2 - item.lStart; * } * if (targetMiddle != null) * targetMiddle.Add(item); * * // item2和Item2不重叠的C部分,留下来做下次循环 * * if (end1 <= end2) * { * if (end1 == end2) * { * item1 = null; * item2 = null; * continue; * } * item2.lStart = end1; * item2.lLength = end2 - end1; * item1 = null; * continue; * } * else * { * item1.lStart = end2; * item1.lLength = end1 - end2; * item2 = null; * continue; * } */ } // item2在前 if (true) { // C部分 long end1 = item1.lStart + item1.lLength; long end2 = item2.lStart + item2.lLength; if (end1 <= end2) { item.lLength = end1 - item.lStart; } else { item.lLength = end2 - item.lStart; } if (targetMiddle != null) { targetMiddle.Add(item); } // item2和Item2不重叠的C部分,留下来做下次循环 if (end1 <= end2) { if (end1 == end2) { item1 = null; item2 = null; continue; } item2.lStart = end1; item2.lLength = end2 - end1; item1 = null; continue; } else { item1.lStart = end2; item1.lLength = end1 - end2; item2 = null; continue; } } // -- C部分 // continue; } // -- 比较两个Item // 只有Item1非空 if (item1 != null) { if (targetLeft != null) { targetLeft.Add(item1); } item1 = null; continue; } // 只有Item2非空 if (item2 != null) { if (targetRight != null) { targetRight.Add(item2); } item2 = null; continue; } } }
// 把一个contentrange字符串按照分块尺寸切割为多个contentrange字符串 // 原理: // 按照数字的个数来切割。和数字本身的值无关。 // 计算把每个连续的段落包含的数字个数,凑够了chunksize就输出字符串。如果不够, // 则把多个段落一起输出为一个字符串。 public static string[] ChunkRange(string strRange, long lChunkSize) { if (lChunkSize <= 0) { throw (new ArgumentException("RangeList.ChunkRange(string strRange, long lChunkSize): lChunkSize参数必须大于0")); } string[] result = null; // 空范围 2006/6/27 if (String.IsNullOrEmpty(strRange) == true) { result = new string[1]; result[0] = strRange; return(result); } RangeList rl = new RangeList(strRange); ArrayList aText = new ArrayList(); long lCurSize = 0; int nStartIndex = 0; for (int i = 0; i < rl.Count; i++) { RangeItem item = (RangeItem)rl[i]; lCurSize += item.lLength; if (lCurSize >= lChunkSize) { string strText = ""; // 从nStart到i之间转换为一个字符串 if (nStartIndex < i) { strText += rl.GetContentRangeString(nStartIndex, i - nStartIndex); strText += ","; } long lDelta = lCurSize - lChunkSize; // i所在位置chunk点左边的转换为一个字符串 strText += Convert.ToString(item.lStart) + "-" + Convert.ToString(item.lStart + item.lLength - 1 - lDelta); // 余下的部分重新写入i位置item if (lDelta > 0) { nStartIndex = i; long lUsed = item.lLength - lDelta; item.lStart += lUsed; item.lLength -= lUsed; i--; } else { nStartIndex = i + 1; } aText.Add(strText); lCurSize = 0; continue; } } // 最后一次 if (nStartIndex < rl.Count) { string strText = ""; // 从nStart到i之间转换为一个字符串 strText += rl.GetContentRangeString(nStartIndex, rl.Count - nStartIndex); aText.Add(strText); } if (aText.Count > 0) { result = new string[aText.Count]; for (int j = 0; j < aText.Count; j++) { result[j] = (string)aText[j]; } } else // 确保数组有至少一个元素 { result = new string[1]; result[0] = strRange; } return(result); }
// 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); }