// 将strRange1中表示的范围减去strRange2的范围,返回 public static string Sub(string strRange1, string strRange2) { RangeList rl1 = new RangeList(strRange1); RangeList rl2 = new RangeList(strRange2); RangeList result = new RangeList(); RangeList.CrossOper(rl1, rl2, result, null, null); return(result.GetContentRangeString()); }
// 合并两个contentrange字符串为一个新串 // parameters: // strS1 第一个范围字符串 // strS2 第二个范围字符串 // lWholeLength 大文件的尺寸。用来检测本次合并后的字符串是否已经完全覆盖整个文件范围 // strResult out参数,返回合并后的字符串 // return // -1 出错 // 0 还有未覆盖的部分 // 1 本次已经完全覆盖 public static int MergeContentRangeString(string strS1, string strS2, long lWholeLength, out string strResult, out string strError) { strError = ""; RangeList rl1 = new RangeList(strS1); RangeList rl2 = new RangeList(strS2); // 组合两个RangeList rl1.AddRange(rl2); // 排序 rl1.Sort(); // 合并事项 rl1.Merge(); // 调试用! // Debug.Assert(rl1.Count == 1, ""); // 返回合并后的contentrange字符串 strResult = rl1.GetContentRangeString(); if (rl1.Count == 1) { RangeItem item = (RangeItem)rl1[0]; if (item.lLength > lWholeLength) { strError = "唯一一个事项的长度 " + item.lLength.ToString() + " 居然大于整体长度 " + lWholeLength.ToString(); return(-1); // 唯一一个事项的长度居然超过检测的长度,通常表明有输入参数错误 } if (item.lStart == 0 && item.lLength == lWholeLength) { return(1); // 表示完全覆盖 } } return(0); // 还有未覆盖的部分 }
// 把一个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); }