// 本函数是将新的记录完整创建好以后再追加到 outputfile 末尾。能确保另一个并发的顺序读操作读入正确的内容 // return: // -1 出错 // 0 因 strXmlBody 为空,忽略此记录,并没有导出任何内容 // 1 导出了内容 static int SafeWriteRecordToBackupFile( IWin32Window owner, RmsChannel channel, DigitalPlatform.Stop stop, Stream outputfile, string strPath, // 记录路径 string strMetaData, string strXmlBody, byte[] body_timestamp, string strTempDir, out string strError) { if (string.IsNullOrEmpty(strTempDir)) { strError = "strTempDir 参数值不应为空"; return(-1); } string strTempFileName = Path.Combine(strTempDir, "~" + Guid.NewGuid().ToString()); try { using (FileStream temp_stream = File.Open( strTempFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.None)) { // return: // -1 出错 // 0 因 strXmlBody 为空,忽略此记录,并没有导出任何内容 // 1 导出了内容 int nRet = WriteRecordToBackupFile( owner, channel, stop, temp_stream, strPath, // 记录路径 strMetaData, strXmlBody, body_timestamp, out strError); if (nRet == -1) { return(-1); } #if NO if (nRet == 1) { // 记忆 dump 前 outputfile 的当前位置 long lSavePosition = outputfile.Position; bool bDone = false; try { temp_stream.Seek(0, SeekOrigin.Begin); // TODO: Dump 中途是否允许灵敏中断?要注意中断以后截断目标文件 long lRet = StreamUtil.LockingDumpStream(temp_stream, outputfile, false, () => { if (stop != null && stop.State != 0) { return(true); } return(false); }); if (lRet == -1) { strError = "Dump 中途被用户中断"; return(-1); } else { bDone = true; } } finally { if (bDone == false) { outputfile.SetLength(lSavePosition); } } } #endif if (nRet == 1) { temp_stream.Seek(0, SeekOrigin.Begin); StreamUtil.LockingDumpStream(temp_stream, outputfile, false, null); } return(nRet); } } catch (Exception ex) { strError = "SafeWriteRecordToBackupFile() 出现异常: " + ExceptionUtil.GetExceptionText(ex); return(-1); } finally { File.Delete(strTempFileName); } }