// 读入一条记录 // return: // -1 出错 // 0 正常 // 1 结束。此次API不返回有效的记录 public int ReadOneRecord(out UploadRecord record, out string strError) { strError = ""; record = null; int nRet = 0; this.Index++; if (this.FileType == ExportFileType.XmlFile) { string strXml = ""; string strPath = ""; string strTimestamp = ""; // 读入一条XML记录 // return: // -1 出错 // 0 正常 // 1 结束。此次API不返回有效的XML记录 nRet = ReadOneXmlRecord(out strXml, out strPath, out strTimestamp); if (nRet == -1) { strError = "ReadOneXmlRecord() 出错"; return -1; } if (nRet == 1) return 1; Debug.Assert(nRet == 0, ""); ResPath respath = new ResPath(strPath); record = new UploadRecord(); record.Url = respath.Url; record.RecordBody = new RecordBody(); record.RecordBody.Xml = strXml; record.RecordBody.Path = respath.Path; // 数据库名/ID record.RecordBody.Timestamp = ByteArray.GetTimeStampByteArray(strTimestamp); return 0; } else if (this.FileType == ExportFileType.BackupFile) { List<OneRes> reslist = null; // 从 .dp2bak 文件中读出每个资源的主要信息 // 本函数调用前,文件指针在整个记录的开始位置 // return: // -1 出错 // 0 正常 // 1 结束。此次API不返回有效的XML记录 nRet = ReadResFrameInfo( out reslist, out strError); if (nRet == -1) return -1; if (nRet == 1) return 1; if (reslist == null || reslist.Count == 0) { strError = "二进制记录内没有包含任何资源"; return -1; } // 第一个资源 Debug.Assert(reslist.Count > 0, ""); OneRes first = reslist[0]; record = new UploadRecord(); record.ResList = reslist; ResPath respath = new ResPath(first.Path); record.Url = respath.Url; record.RecordBody = new RecordBody(); record.RecordBody.Xml = ""; record.RecordBody.Path = respath.Path; // 数据库名/ID record.RecordBody.Timestamp = first.Timestamp; // 如果第一个资源的尺寸不是太大,还要取得 XML 字符串 if (first.Length < 500 * 1024) { long lSave = this.Stream.Position; try { this.Stream.Seek(first.StartOffs, SeekOrigin.Begin); byte[] baContent = new byte[(int)first.Length]; int nCount = this.Stream.Read(baContent, 0, baContent.Length); if (nCount < baContent.Length) { strError = "读取XML字符串时超过文件尾部"; return -1; } // 转换成字符串 record.RecordBody.Xml = ByteArray.ToString(baContent); } finally { // TODO: 移动指针的动作可以优化 this.Stream.Seek(lSave, SeekOrigin.Begin); } } return 0; } else if (this.FileType == ExportFileType.ISO2709File) { string strMARC = ""; // 从ISO2709文件中读入一条MARC记录 // return: // -2 MARC格式错 // -1 出错 // 0 正确 // 1 结束(当前返回的记录有效) // 2 结束(当前返回的记录无效) nRet = MarcUtil.ReadMarcRecord(this.Stream, this.Encoding, true, // bRemoveEndCrLf, true, // bForce, out strMARC, out strError); if (nRet == -2 || nRet == -1) { strError = "读入MARC记录时出错: " + strError; return -1; } if (nRet == 2) return 1; #if NO // 测试 if (this.Index >= 50000) return 1; #endif Debug.Assert(nRet == 0 || nRet == 1, ""); string strXml = ""; // 将MARC记录转换为xml格式 nRet = MarcUtil.Marc2Xml(strMARC, this.MarcSyntax, out strXml, out strError); if (nRet == -1) return -1; record = new UploadRecord(); record.RecordBody = new RecordBody(); record.RecordBody.Xml = strXml; record.RecordBody.Path = ""; record.RecordBody.Timestamp = null; return 0; } return 0; }
// 写入一条 XML 记录 // return: // -1 出错 // 0 邀请中断整个处理 // 1 成功 // 2 跳过本条,继续处理后面的 public static int WriteOneXmlRecord( IWin32Window owner, Stop stop, RmsChannel channel, UploadRecord record, ref bool bDontPromptTimestampMismatchWhenOverwrite, out string strError) { strError = ""; string strWarning = ""; // 询问库名映射关系 string strTargetPath = record.RecordBody.Path; byte[] output_timestamp = null; string strOutputPath = ""; REDOSAVE: // 保存Xml记录 long lRet = channel.DoSaveTextRes(strTargetPath, record.RecordBody.Xml, false, // bIncludePreamble "", // bFastMode == true ? "fastmode" : "",//strStyle, record.RecordBody.Timestamp, out output_timestamp, out strOutputPath, out strError); if (lRet == -1) return -1; if (lRet == -1) { if (stop != null) stop.Continue(); if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch) { string strDisplayRecPath = strOutputPath; if (string.IsNullOrEmpty(strDisplayRecPath) == true) strDisplayRecPath = strTargetPath; if (bDontPromptTimestampMismatchWhenOverwrite == true) { record.RecordBody.Timestamp = output_timestamp; strWarning = " (时间戳不匹配, 自动重试)"; // TODO: 如何防止死循环? goto REDOSAVE; } string strText = "保存 '" + strDisplayRecPath + " 时发现时间戳不匹配。详细情况如下:\r\n---\r\n" + strError + "\r\n---\r\n\r\n是否以新时间戳强行覆盖保存?\r\n注:\r\n[是] 强行覆盖保存\r\n[否] 忽略当前记录或资源保存,但继续后面的处理\r\n[取消] 中断整个批处理"; //WriteLog("打开对话框 '" + strText.Replace("\r\n", "\\n") + "'"); DialogResult result = MessageDlg.Show(owner, strText, "dp2batch", MessageBoxButtons.YesNoCancel, MessageBoxDefaultButton.Button1, ref bDontPromptTimestampMismatchWhenOverwrite); //WriteLog("关闭对话框 '" + strText.Replace("\r\n", "\\n") + "'"); if (result == DialogResult.Yes) { record.RecordBody.Timestamp = output_timestamp; strWarning = " (时间戳不匹配, 应用户要求重试)"; goto REDOSAVE; } if (result == DialogResult.No) { return 2; // 继续作后面的资源 } if (result == DialogResult.Cancel) { strError = "用户中断"; return 0; // 中断整个处理 } } // 询问是否重试 { string strText = "保存 '" + strTargetPath + " 时发生错误。详细情况如下:\r\n---\r\n" + strError + "\r\n---\r\n\r\n是否重试?\r\n注:(是)重试 (否)不重试,但继续后面的处理 (取消)中断整个批处理"; //WriteLog("打开对话框 '" + strText.Replace("\r\n", "\\n") + "'"); DialogResult result1 = MessageBox.Show(owner, strText, "dp2batch", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); //WriteLog("关闭对话框 '" + strText.Replace("\r\n", "\\n") + "'"); if (result1 == DialogResult.Yes) goto REDOSAVE; if (result1 == DialogResult.No) return 2; // 继续作后面的资源 } return -1; } return 1; }