public IEnumerator GetEnumerator() { string strError = ""; string strRange = "0-9999999999"; long lTotalCount = 0; // 总命中数 long lExportCount = 0; string strTimeMessage = ""; DigitalPlatform.Stop stop = this.Stop; StopStyle old_style = StopStyle.None; if (stop != null) { old_style = stop.Style; stop.Style = StopStyle.EnableHalfStop; // API的间隙才让中断。避免获取结果集的中途,因为中断而导致 Session 失效,结果集丢失,进而无法 Retry 获取 stop.OnStop += stop_OnStop; } ProgressEstimate estimate = new ProgressEstimate(); try { int i_path = 0; foreach (string path in this.Paths) { ResPath respath = new ResPath(path); string strQueryXml = "<target list='" + respath.Path + ":" + "__id'><item><word>" + strRange + "</word><match>exact</match><relation>range</relation><dataType>number</dataType><maxCount>-1</maxCount></item><lang>chi</lang></target>"; cur_channel = Channels.CreateTempChannel(respath.Url); Debug.Assert(cur_channel != null, "Channels.GetChannel() 异常"); try { long lRet = cur_channel.DoSearch(strQueryXml, "default", out strError); if (lRet == -1) { strError = "检索数据库 '" + respath.Path + "' 时出错: " + strError; throw new Exception(strError); } if (lRet == 0) { strError = "数据库 '" + respath.Path + "' 中没有任何数据记录"; continue; } lTotalCount += lRet; // 总命中数 estimate.SetRange(0, lTotalCount); if (i_path == 0) { estimate.StartEstimate(); } if (stop != null) { stop.SetProgressRange(0, lTotalCount); } SearchResultLoader loader = new SearchResultLoader(cur_channel, stop, this.ResultSetName, this.FormatList, this.Lang); loader.BatchSize = this.BatchSize; foreach (KernelRecord record in loader) { if (stop != null) { stop.SetProgressValue(lExportCount + 1); } lExportCount++; yield return(record); } strTimeMessage = "总共耗费时间: " + estimate.GetTotalTime().ToString(); } finally { cur_channel.Close(); cur_channel = null; } // MessageBox.Show(this, "位于服务器 '" + respath.Url + "' 上的数据库 '" + respath.Path + "' 内共有记录 " + lTotalCount.ToString() + " 条,本次导出 " + lExportCount.ToString() + " 条。" + strTimeMessage); i_path++; } } finally { if (stop != null) { stop.Style = old_style; stop.OnStop -= stop_OnStop; } } }
// 上传文件到到 dp2lbrary 服务器 // parameters: // timestamp 时间戳。如果为 null,函数会自动根据文件信息得到一个时间戳 // bRetryOverwiteExisting 是否自动在时间戳不一致的情况下覆盖已经存在的服务器文件。== true,表示当发现时间戳不一致的时候,自动用返回的时间戳重试覆盖 // return: // -1 出错 // 0 上传文件成功 public int UploadFile( string strClientFilePath, string strServerFilePath, string strStyle, byte[] timestamp, bool bRetryOverwiteExisting, out string strError) { strError = ""; StopStyle old_stop_style = StopStyle.None; if (this.stop != null) { old_stop_style = this.stop.Style; this.stop.Style = StopStyle.EnableHalfStop; this.stop.OnStop += new StopEventHandler(this.DoStop); this.stop.Initial("正在上传文件 ..."); this.stop.BeginLoop(); } try { string strResPath = strServerFilePath; #if NO string strMime = API.MimeTypeFrom(ResObjectDlg.ReadFirst256Bytes(strClientFilePath), ""); #endif string strMime = PathUtil.MimeTypeFrom(strClientFilePath); // 检测文件尺寸 FileInfo fi = new FileInfo(strClientFilePath); if (fi.Exists == false) { strError = "文件 '" + strClientFilePath + "' 不存在..."; return(-1); } string[] ranges = null; if (fi.Length == 0) { // 空文件 ranges = new string[1]; ranges[0] = ""; } else { string strRange = ""; strRange = "0-" + Convert.ToString(fi.Length - 1); // 按照100K作为一个chunk // TODO: 实现滑动窗口,根据速率来决定chunk尺寸 ranges = RangeList.ChunkRange(strRange, this.Channel.UploadResChunkSize // 500 * 1024 ); } if (timestamp == null) { timestamp = FileUtil.GetFileTimestamp(strClientFilePath); } byte[] output_timestamp = null; // REDOWHOLESAVE: string strWarning = ""; for (int j = 0; j < ranges.Length; j++) { // REDOSINGLESAVE: Application.DoEvents(); // 出让界面控制权 if (this.stop.State != 0) { strError = "用户中断"; goto ERROR1; } string strWaiting = ""; if (j == ranges.Length - 1) { strWaiting = " 请耐心等待..."; } string strPercent = ""; RangeList rl = new RangeList(ranges[j]); if (rl.Count >= 1) { double ratio = (double)((RangeItem)rl[0]).lStart / (double)fi.Length; strPercent = String.Format("{0,3:N}", ratio * (double)100) + "%"; } if (this.stop != null) { this.stop.SetMessage("正在上载 " + ranges[j] + "/" + Convert.ToString(fi.Length) + " " + strPercent + " " + strClientFilePath + strWarning + strWaiting); } int nRedoCount = 0; REDO: long lRet = this.Channel.SaveResObject( this.stop, strResPath, strClientFilePath, strClientFilePath, strMime, ranges[j], // j == ranges.Length - 1 ? true : false, // 最尾一次操作,提醒底层注意设置特殊的WebService API超时时间 timestamp, strStyle, out output_timestamp, out strError); timestamp = output_timestamp; strWarning = ""; if (lRet == -1) { // 如果是第一个 chunk,自动用返回的时间戳重试一次覆盖 if (bRetryOverwiteExisting == true && j == 0 && this.Channel.ErrorCode == DigitalPlatform.LibraryClient.localhost.ErrorCode.TimestampMismatch && nRedoCount == 0) { nRedoCount++; goto REDO; } goto ERROR1; } } return(0); ERROR1: return(-1); } finally { if (this.stop != null) { this.stop.EndLoop(); this.stop.OnStop -= new StopEventHandler(this.DoStop); this.stop.Initial("上传文件完成"); this.stop.Style = old_stop_style; } } }
// 保存资源到服务器 // return: // -1 error // >=0 实际上载的资源对象数 public int Save( LibraryChannel channel, Stop stop, string strHostRecPath, string dp2library_version, out string strError) { strError = ""; if (this.Count == 0) { return(0); } this.HostRecPath = strHostRecPath; // 2016/10/15 #if NO if (String.IsNullOrEmpty(this.HostRecPath) == true) { strError = "尚未指定 BiblioRecPath"; return(-1); } #endif if (IsNewPath(this.HostRecPath) == true) { strError = "宿主记录路径 '" + this.HostRecPath + "' 不是已保存的记录路径,无法用于对象资源上载"; return(-1); } StopStyle old_stop_style = StopStyle.None; if (stop != null) { old_stop_style = stop.Style; stop.Style = StopStyle.EnableHalfStop; stop.Initial("正在上载资源 ..."); } int nUploadCount = 0; // 实际上载的资源个数 List <ObjectInfo> delete_objects = new List <ObjectInfo>(); try { foreach (ObjectInfo obj in this) { // LineInfo info = (LineInfo)item.Tag; LineState state = obj.LineState; bool bOnlyChangeMetadata = false; if (state == LineState.Changed || state == LineState.New) { if (state == LineState.Changed) { if (obj != null && obj.ResChanged == false) { if (StringUtil.CompareVersion(dp2library_version, "2.59") < 0) { strError = "单独修改对象 metadata 的操作需要连接的 dp2library 版本在 2.59 以上 (然而当前 dp2library 版本为 " + dp2library_version + ")"; return(-1); } // 这种情况应该是 metadata 修改过 bOnlyChangeMetadata = true; } } } else { // 标记删除的事项,只要书目XML重新构造的时候 // 不包含其ID,书目XML保存后,就等于删除了该事项。 // 所以本函数只是简单Remove这样的listview事项即可 if (state == LineState.Deleted) { delete_objects.Add(obj); } continue; } // string strState = ListViewUtil.GetItemText(item, COLUMN_STATE); string strResPath = this.HostRecPath + "/object/" + obj.ID; byte[] timestamp = ByteArray.GetTimeStampByteArray(obj.Timestamp); byte[] output_timestamp = null; nUploadCount++; if (bOnlyChangeMetadata) { long lRet = channel.SaveResObject( stop, strResPath, "", // obj.FileName, // obj.Mime, obj.Metadata, "", // range true, // 最尾一次操作,提醒底层注意设置特殊的WebService API超时时间 timestamp, out output_timestamp, out strError); timestamp = output_timestamp; if (timestamp != null) { obj.Timestamp = ByteArray.GetHexTimeStampString(timestamp); } if (lRet == -1) { goto ERROR1; } Debug.Assert(timestamp != null, ""); // TODO: 出错的情况下是否要修改 timestamp 显示?是否应为非空才兑现显示 } else { // 检测文件尺寸 FileInfo fi = new FileInfo(obj.FileName); if (fi.Exists == false) { strError = "文件 '" + obj.FileName + "' 不存在..."; return(-1); } string[] ranges = null; if (fi.Length == 0) { // 空文件 ranges = new string[1]; ranges[0] = ""; } else { string strRange = ""; strRange = "0-" + Convert.ToString(fi.Length - 1); // 按照100K作为一个chunk // TODO: 实现滑动窗口,根据速率来决定chunk尺寸 ranges = RangeList.ChunkRange(strRange, channel.UploadResChunkSize // 500 * 1024 ); } // REDOWHOLESAVE: string strWarning = ""; for (int j = 0; j < ranges.Length; j++) { // Application.DoEvents(); // 出让界面控制权 if (stop != null && stop.State != 0) { strError = "用户中断"; goto ERROR1; } string strWaiting = ""; if (j == ranges.Length - 1) { strWaiting = " 请耐心等待..."; } string strPercent = ""; RangeList rl = new RangeList(ranges[j]); if (rl.Count >= 1) { double ratio = (double)((RangeItem)rl[0]).lStart / (double)fi.Length; strPercent = String.Format("{0,3:N}", ratio * (double)100) + "%"; } if (stop != null) { stop.SetMessage("正在上载 " + ranges[j] + "/" + Convert.ToString(fi.Length) + " " + strPercent + " " + obj.FileName + strWarning + strWaiting); } long lRet = 0; TimeSpan old_timeout = channel.Timeout; channel.Timeout = new TimeSpan(0, 5, 0); try { lRet = channel.SaveResObject( stop, strResPath, obj.FileName, //obj.FileName, //obj.Mime, obj.Metadata, ranges[j], j == ranges.Length - 1 ? true : false, // 最尾一次操作,提醒底层注意设置特殊的WebService API超时时间 timestamp, out output_timestamp, out strError); } finally { channel.Timeout = old_timeout; } timestamp = output_timestamp; if (timestamp != null) { obj.Timestamp = ByteArray.GetHexTimeStampString(timestamp); } strWarning = ""; if (lRet == -1) { goto ERROR1; } } } obj.LineState = LineState.Normal; obj.XmlChanged = false; obj.ResChanged = false; } this.Changed = false; return(nUploadCount); ERROR1: return(-1); } finally { if (stop != null) { if (nUploadCount > 0) { stop.Initial("上载资源完成"); } else { stop.Initial(""); } } } }
private void button_download_Click(object sender, EventArgs e) { string strError = ""; if (string.IsNullOrEmpty(this.textBox_serverFilePath.Text) == true) { strError = "尚未指定服务器端文件路径"; goto ERROR1; } if (string.IsNullOrEmpty(this.textBox_clientFilePath.Text) == true) { strError = "尚未指定前端文件路径"; goto ERROR1; } StopStyle old_stop_style = StopStyle.None; old_stop_style = this.stop.Style; this.stop.Style = StopStyle.EnableHalfStop; this.stop.OnStop += new StopEventHandler(this.DoStop); this.stop.Initial("正在下载文件 ..."); this.stop.BeginLoop(); this.EnableControls(false); try { string strMetaData = ""; byte[] baOutputTimeStamp = null; string strOutputPath = ""; // parameters: // strOutputFileName 输出文件名。可以为null。如果调用前文件已经存在, 会被覆盖。 // return: // -1 出错。具体出错原因在this.ErrorCode中。this.ErrorInfo中有出错信息。 // 0 成功 long lRet = this.Channel.GetRes( this.stop, this.textBox_serverFilePath.Text, this.textBox_clientFilePath.Text, out strMetaData, out baOutputTimeStamp, out strOutputPath, out strError); if (lRet == -1) { goto ERROR1; } // 根据返回的时间戳设置文件最后修改时间 FileUtil.SetFileLastWriteTimeByTimestamp(this.textBox_clientFilePath.Text, baOutputTimeStamp); } finally { this.stop.EndLoop(); this.stop.OnStop -= new StopEventHandler(this.DoStop); this.stop.Initial("下载文件完成"); this.stop.Style = old_stop_style; this.EnableControls(true); } return; ERROR1: MessageBox.Show(this, strError); }