Example #1
0
        // return:
        //      -1  出错
        //      0   正常结束
        //      1   中断
        /// <summary>
        /// 处理日志文件
        /// </summary>
        /// <param name="owner">宿主窗口</param>
        /// <param name="stop">停止对象</param>
        /// <param name="estimate">剩余时间估算器</param>
        /// <param name="channel">通讯通道</param>
        /// <param name="filenames">要参与处理的日志文件名集合</param>
        /// <param name="nLevel">从 dp2Library 服务器获取日志记录的详细级别</param>
        /// <param name="strStyle">处理风格。autocache</param>
        /// <param name="strCacheDir">日志本地缓存目录</param>
        /// <param name="param">回调对象</param>
        /// <param name="procDoRecord">回调函数</param>
        /// <param name="strError">返回出错信息</param>
        /// <returns>
        ///      -1  出错
        ///      0   正常结束
        ///      1   中断
        /// </returns>
        public static int ProcessFiles(
            IWin32Window owner,
            Stop stop,
            ProgressEstimate estimate,
            LibraryChannel channel,
            List<string> filenames,
            int nLevel,
            string strStyle,
            string strCacheDir,
            object param,
            Delegate_doRecord procDoRecord,
            out string strError)
        {
            strError = "";
            int nRet = 0;

            bool bAccessLog = StringUtil.IsInList("accessLog", strStyle);

            if (string.IsNullOrEmpty(strCacheDir) == false)
                PathUtil.CreateDirIfNeed(strCacheDir);

            // ProgressEstimate estimate = new ProgressEstimate();
            bool bAutoCache = StringUtil.IsInList("autocache", strStyle);

            if (bAutoCache == true)
            {
                long lServerFileSize = 0;
                long lCacheFileSize = 0;
                // 象征性获得一个日志文件的尺寸,主要目的是为了触发一次通道登录
                // return:
                //      -1  error
                //      0   file not found
                //      1   found
                nRet = GetFileSize(
                    stop,
                    channel,
                    strCacheDir,
                    "20121001.log",
                    bAccessLog,
                    out lServerFileSize,
                    out lCacheFileSize,
                    out strError);
                if (nRet == -1)
                    return -1;

                // 检查日志文件缓存目录的版本是否和当前用户的信息一致
                // return:
                //      -1  出错
                //      0   一致
                //      1   不一致
                nRet = DetectCacheVersionFile(
                    strCacheDir,
                    "version.xml",
                    channel.LibraryCodeList,
                    channel.Url,
                    out strError);
                if (nRet == -1)
                    return -1;
                if (nRet == 1)
                {
                    // 清空当前缓存目录
                    nRet = Global.DeleteDataDir(
                        owner,
                        strCacheDir,
                        out strError);
                    if (nRet == -1)
                        return -1;
                    PathUtil.CreateDirIfNeed(strCacheDir);  // 重新创建目录

                    // 创建版本文件
                    nRet = CreateCacheVersionFile(
                        strCacheDir,
                        "version.xml",
                        channel.LibraryCodeList,
                        channel.Url,
                        out strError);
                    if (nRet == -1)
                        return -1;
                }
            }

            long lTotalSize = 0;
            List<string> lines = new List<string>();    // 经过处理后排除了不存在的文件名
            List<long> sizes = new List<long>();
            stop.SetMessage("正在准备获得日志文件尺寸 ...");
            foreach (string strLine in filenames)
            {
                Application.DoEvents();

                if (stop != null && stop.State != 0)
                {
                    strError = "用户中断";
                    return 1;
                }

                if (String.IsNullOrEmpty(strLine) == true)
                    continue;

                string strFilename = strLine.Trim();
                // 去掉注释
                nRet = strFilename.IndexOf("#");
                if (nRet != -1)
                    strFilename = strFilename.Substring(0, nRet).Trim();

                if (String.IsNullOrEmpty(strFilename) == true)
                    continue;

                string strLogFilename = "";
                string strRange = "";

                nRet = strFilename.IndexOf(":");
                if (nRet != -1)
                {
                    strLogFilename = strFilename.Substring(0, nRet).Trim();
                    strRange = strFilename.Substring(nRet + 1).Trim();
                }
                else
                {
                    strLogFilename = strFilename.Trim();
                    strRange = "";
                }

                long lServerFileSize = 0;
                long lCacheFileSize = 0;
                // 获得一个日志文件的尺寸
                // return:
                //      -1  error
                //      0   file not found
                //      1   found
                nRet = GetFileSize(
                    stop,
                    channel,
                    strCacheDir,
                    strLogFilename,
                    bAccessLog,
                    out lServerFileSize,
                    out lCacheFileSize,
                    out strError);
                if (nRet == -1)
                    return -1;

                if (nRet == 0)
                    continue;

                if (lServerFileSize == 0)
                    continue;   // 0字节的文件当作不存在处理

                Debug.Assert(lServerFileSize >= 0, "");

                if (bAutoCache == true)
                {
                    if (lCacheFileSize > 0)
                        lTotalSize += lCacheFileSize;
                    else
                        lTotalSize += lServerFileSize;
                }
                else
                {
                    lTotalSize += lServerFileSize;
                }

                lines.Add(strFilename);

                // 记忆每个文件的尺寸,后面就不用获取了?
                sizes.Add(lServerFileSize);
            }

            if (stop != null)
                stop.SetProgressRange(0, lTotalSize);

            estimate.SetRange(0, lTotalSize);
            estimate.StartEstimate();

            long lDoneSize = 0;
            for (int i = 0; i < lines.Count; i++)
            {
                Application.DoEvents();

                if (stop != null && stop.State != 0)
                {
                    strError = "用户中断";
                    return 1;
                }

                string strLine = lines[i];
#if NO
                    if (String.IsNullOrEmpty(strLine) == true)
                        continue;
                    // 去掉注释
                    nRet = strLine.IndexOf("#");
                    if (nRet != -1)
                        strLine = strLine.Substring(0, nRet).Trim();

                    if (String.IsNullOrEmpty(strLine) == true)
                        continue;
#endif

                string strLogFilename = "";
                string strRange = "";

                nRet = strLine.IndexOf(":");
                if (nRet != -1)
                {
                    strLogFilename = strLine.Substring(0, nRet).Trim();
                    strRange = strLine.Substring(nRet + 1).Trim();
                }
                else
                {
                    strLogFilename = strLine.Trim();
                    strRange = "";
                }

                // return:
                //      -1  error
                //      0   正常结束
                //      1   用户中断
                nRet = ProcessFile(
                    owner,
                    stop,
                    estimate,
                    channel,
                    strLogFilename,
                    nLevel,
                    sizes[i],
                    strRange,
                    strStyle,
                    strCacheDir,
                    param,
                    procDoRecord,
                    ref lDoneSize,
                    ref lTotalSize,
                    out strError);
                if (nRet == -1)
                {
                    if (stop != null)
                    {
                        if (stop.State != 0)
                            return 0;
                    }
                    // MessageBox.Show(this, strError);
                    DialogResult result = MessageBox.Show(owner,
strError + "\r\n\r\n是否继续处理?",
"OperLogForm",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question,
MessageBoxDefaultButton.Button1);
                    if (result == DialogResult.No)
                        return 1;
                }
                if (nRet == 1)
                    return 1;
            }

            return 0;
        }
Example #2
0
        // 装入一个日志文件中的若干记录
        // parameters:
        //      strStyle    如果包含 accessLog,表示这是需要获取只读日志
        //      strCacheDir 存储本地缓存文件的目录
        //      lServerFileSize 服务器端日志文件的尺寸。如果为-1,表示函数内会自动获取
        //      lSize   进度条所采用的最大尺寸。如果必要,可能会被本函数推动
        // return:
        //      -2  此类型的日志尚未启用
        //      -1  error
        //      0   正常结束
        //      1   用户中断
        static int ProcessFile(
            IWin32Window owner,
            Stop stop,
            ProgressEstimate estimate,
            LibraryChannel channel,
            string strLogFileName,
            int nLevel,
            long lServerFileSize,
            string strRange,
            string strStyle,
            string strCacheDir,
            object param,
            Delegate_doRecord procDoRecord,
            ref long lProgressValue,
            ref long lSize,
            out string strError)
        {
            strError = "";
            int nRet = 0;
            long lRet = 0;

            stop.SetMessage("正在装入日志文件 " + strLogFileName + " 中的记录。"
                + "剩余时间 " + ProgressEstimate.Format(estimate.Estimate(lProgressValue)) + " 已经过时间 " + ProgressEstimate.Format(estimate.delta_passed));

            bool bAccessLog = StringUtil.IsInList("accessLog", strStyle);

            string strXml = "";
            long lAttachmentTotalLength = 0;
            byte[] attachment_data = null;

            long lFileSize = 0;
            if (lServerFileSize == -1)
            {
                lServerFileSize = 0;

                string strTempStyle = "level-" + nLevel.ToString();
                if (bAccessLog)
                    strTempStyle += ",accessLog";

                // 获得服务器端日志文件尺寸
                lRet = channel.GetOperLog(
                    stop,
                    strLogFileName,
                    -1,    // lIndex,
                    -1, // lHint,
                    strTempStyle,
                    "", // strFilter
                    out strXml,
                    out lServerFileSize,
                    0,  // lAttachmentFragmentStart,
                    0,  // nAttachmentFramengLength,
                    out attachment_data,
                    out lAttachmentTotalLength,
                    out strError);
                // 2015/11/25
                if (lRet == -1)
                    return -1;
                // 2010/12/13
                if (lRet == 0)
                    return 0;
                if (lServerFileSize == -1)
                {
                    strError = "日志尚未启用";
                    return -2;
                }
            }

            Stream stream = null;
            bool bCacheFileExist = false;
            bool bRemoveCacheFile = false;  // 是否要自动删除未全部完成的本地缓存文件

            bool bAutoCache = StringUtil.IsInList("autocache", strStyle);

            if (bAutoCache == true)
            {
                nRet = PrepareCacheFile(
                    strCacheDir,
                    bAccessLog ? strLogFileName + ".a" : strLogFileName,
                    lServerFileSize,
                    out bCacheFileExist,
                    out stream,
                    out strError);
                if (nRet == -1)
                    return -1;

                if (bCacheFileExist == false && stream != null)
                    bRemoveCacheFile = true;
            }

            try
            {
                if (bCacheFileExist == true)
                    lFileSize = stream.Length;
                else
                    lFileSize = lServerFileSize;

                // stop.SetProgressRange(0, lTotalSize);

                if (String.IsNullOrEmpty(strRange) == true)
                    strRange = "0-9999999999";

                RangeList rl = new RangeList(strRange);

                for (int i = 0; i < rl.Count; i++)
                {
                    RangeItem ri = (RangeItem)rl[i];

                    OperLogInfo[] records = null;
                    long lStartRecords = 0;

                    long lHint = -1;
                    long lHintNext = -1;
                    for (long lIndex = ri.lStart; lIndex < ri.lStart + ri.lLength; lIndex++)
                    {
                        Application.DoEvents();

                        if (stop != null)
                        {
                            if (stop.State != 0)
                            {
                                strError = "用户中断1";
                                goto ERROR1;
                            }
                        }

                        if (lIndex == ri.lStart)
                            lHint = -1;
                        else
                            lHint = lHintNext;

                        if (bCacheFileExist == true)
                        {
                            if (lHint == -1)
                            {
                                // return:
                                //      -1  error
                                //      0   成功
                                //      1   到达文件末尾或者超出
                                nRet = LocationRecord(stream,
                    lIndex,
                    out strError);
                                if (nRet == -1)
                                    return -1;
                            }
                            else
                            {
                                // 根据暗示找到
                                if (lHint == stream.Length)
                                    break;

                                if (lHint > stream.Length)
                                {
                                    strError = "lHint参数值不正确";
                                    return -1;
                                }
                                if (stream.Position != lHint)
                                    stream.Seek(lHint, SeekOrigin.Begin);
                            }

                            nRet = ReadCachedEnventLog(
                                stream,
                                out strXml,
                                out lAttachmentTotalLength,
                                out strError);
                            if (nRet == -1)
                                return -1;
                            lHintNext = stream.Position;

                        }
                        else
                        {
                            if (records == null || lIndex - ri.lStart >= lStartRecords + records.Length)
                            {
                                int nCount = -1;
                                if (ri.lLength >= Int32.MaxValue)
                                    nCount = -1;
                                else
                                    nCount = (int)ri.lLength;

                                string strTempStyle = "level-" + nLevel.ToString();
                                if (bAccessLog)
                                    strTempStyle += ",accessLog";
                                // 获得日志
                                // return:
                                //      -1  error
                                //      0   file not found
                                //      1   succeed
                                //      2   超过范围,本次调用无效
                                lRet = channel.GetOperLogs(
                                    stop,
                                    strLogFileName,
                                    lIndex,
                                    lHint,
                                    nCount,
                                    strTempStyle,
                                    "", // strFilter
                                    out records,
                                    out strError);
                                if (lRet == -1)
                                {
                                    DialogResult result = MessageBox.Show(owner,
    strError + "\r\n\r\n是否继续处理?",
    "OperLogForm",
    MessageBoxButtons.YesNo,
    MessageBoxIcon.Question,
    MessageBoxDefaultButton.Button1);
                                    if (result == DialogResult.No)
                                        goto ERROR1;
                                    else
                                    {
                                        // TODO: 是否要在listview中装入一条表示出错的行?
                                        lHintNext = -1;
                                        continue;
                                    }
                                }
                                if (lRet == 0)
                                    return 0;

                                if (lRet == 2)
                                    break;

                                // records数组表示的起点位置
                                lStartRecords = lIndex - ri.lStart;
                            }
                            OperLogInfo info = records[lIndex - lStartRecords];

                            strXml = info.Xml;
                            lHintNext = info.HintNext;
                            lAttachmentTotalLength = info.AttachmentLength;

                            // 写入本地缓存的日志文件
                            if (stream != null)
                            {
                                try
                                {
                                    WriteCachedEnventLog(
                                        stream,
                                        strXml,
                                        lAttachmentTotalLength);
                                }
                                catch (Exception ex)
                                {
                                    strError = "写入本地缓存文件的时候出错: " + ex.Message;
                                    return -1;
                                }
                            }
                        }

#if NO
                            // 2011/12/30
                            // 日志记录可能动态地增加了,超过了原先为ProgressBar设置的范围
                            if (lFizeTotalSize < (int)lHintNext)
                            {
                                lFizeTotalSize = lHintNext;

                                stop.SetProgressRange(0, lFizeTotalSize);
                            }
#endif
                        if (lHintNext >= 0)
                        {
                            // 校正
                            if (lProgressValue + lHintNext > lSize)
                            {
                                lSize = lProgressValue + lHintNext;

                                stop.SetProgressRange(0, lSize);
                                estimate.SetRange(0, lSize);
                            }

                            stop.SetProgressValue(lProgressValue + lHintNext);
                        }

                        if (lIndex % 100 == 0)
                        {
                            stop.SetMessage("正在装入日志文件 " + strLogFileName + " 中的记录 " + lIndex.ToString() + " 。"
    + "剩余时间 " + ProgressEstimate.Format(estimate.Estimate(lProgressValue + lHintNext)) + " 已经过时间 " + ProgressEstimate.Format(estimate.delta_passed));
                        }

                        //
                        if (procDoRecord != null)
                        {
                            nRet = procDoRecord(strLogFileName,
        strXml,
        bCacheFileExist,
        lHint,
        lIndex,
        lAttachmentTotalLength,
        param,
        out strError);
                            if (nRet == -1)
                            {
                                DialogResult result = MessageBox.Show(owner,
                                    strLogFileName + " : " + lIndex.ToString() + "\r\n" + strError + "\r\n\r\n是否继续处理?",
"OperLogForm",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question,
MessageBoxDefaultButton.Button1);
                                if (result == DialogResult.No)
                                    return -1;
                            }
                            if (nRet == 1)
                                return 1;
                        }

                    }
                }

                // 创建本地缓存的日志文件的metadata文件
                if (bCacheFileExist == false && stream != null)
                {
                    nRet = CreateCacheMetadataFile(
                        strCacheDir,
                        bAccessLog ? strLogFileName + ".a" : strLogFileName,
                        lServerFileSize,
                        out strError);
                    if (nRet == -1)
                        goto ERROR1;
                }

                bRemoveCacheFile = false;   // 不删除
            }
            finally
            {
                if (stream != null)
                    stream.Close();

                if (bRemoveCacheFile == true)
                {
                    string strError1 = "";
                    nRet = DeleteCacheFile(
                        strCacheDir,
                        bAccessLog ? strLogFileName + ".a" : strLogFileName,
                        out strError1);
                    if (nRet == -1)
                        MessageBox.Show(owner, strError1);
                }
            }

            lProgressValue += lFileSize;
            return 0;
        ERROR1:
            return -1;
        }
Example #3
0
        void RefreshLines(List<ListViewItem> items,
    bool bFillBiblioSummary)
        {
            string strError = "";
            string strTimeMessage = "";
            int nRet = 0;

            EnableControls(false);
            // MainForm.ShowProgress(true);

            stop.OnStop += new StopEventHandler(this.DoStop);
            stop.Initial("正在刷新 ...");
            stop.BeginLoop();

            try
            {
                stop.SetProgressRange(0, items.Count);
                ProgressEstimate estimate = new ProgressEstimate();
                estimate.SetRange(0, items.Count);
                estimate.Start();

                int nLineCount = 0;
                List<string> lines = new List<string>();
                List<ListViewItem> part_items = new List<ListViewItem>();
                for (int i = 0; i < items.Count; i++)
                {
                    if (stop.State != 0)
                    {
                        strError = "用户中断1";
                        goto ERROR1;
                    }

                    ListViewItem item = items[i];

                    stop.SetMessage("正在刷新 " + item.Text + " ...");
                    stop.SetProgressValue(i);

                    string strRecPath = ListViewUtil.GetItemText(item, COLUMN_RECPATH);

                    lines.Add(strRecPath);
                    part_items.Add(item);
                    if (lines.Count >= 100)
                    {
                        if (lines.Count > 0)
                            stop.SetMessage("(" + i.ToString() + " / " + nLineCount.ToString() + ") 正在装入路径 " + lines[0] + " 等记录。"
                                + "剩余时间 " + ProgressEstimate.Format(estimate.Estimate(i)) + " 已经过时间 " + ProgressEstimate.Format(estimate.delta_passed));

                        // 处理一小批记录的装入
                        nRet = DoLoadRecords(lines,
                            part_items,
                            bFillBiblioSummary,
                            new string [] {"summary","@isbnissn"},
                            out strError);
                        if (nRet == -1)
                            goto ERROR1;
                        lines.Clear();
                        part_items.Clear();
                    }
                }

                // 最后剩下的一批
                if (lines.Count > 0)
                {
                    if (lines.Count > 0)
                        stop.SetMessage("(" + nLineCount.ToString() + " / " + nLineCount.ToString() + ") 正在装入路径 " + lines[0] + " 等记录...");

                    // 处理一小批记录的装入
                    nRet = DoLoadRecords(lines,
                        part_items,
                        bFillBiblioSummary,
                        new string[] { "summary", "@isbnissn" },
                        out strError);
                    if (nRet == -1)
                        goto ERROR1;
                    lines.Clear();
                    part_items.Clear();
                }

                strTimeMessage = "共刷新册信息 " + nLineCount.ToString() + " 条。耗费时间: " + estimate.GetTotalTime().ToString();

            }
            finally
            {
                stop.EndLoop();
                stop.OnStop -= new StopEventHandler(this.DoStop);
                stop.Initial("刷新完成。");
                stop.HideProgress();

                EnableControls(true);
                // MainForm.ShowProgress(false);
            }
            return;
        ERROR1:
            MessageBox.Show(this, strError);
        }
Example #4
0
        // 对每个日志文件,每个日志记录进行循环
        // return:
        //      0   普通返回
        //      1   要全部中断
        int DoLoop(
            OperLogForm.Delegate_doRecord procDoRecord,
            out string strError)
        {
            strError = "";
            int nRet = 0;
            // long lRet = 0;

            List<string> LogFileNames = null;

            // TODO: 是否需要检查起止日期是否为空值?空值是警告还是就当作今天?

            string strStartDate = DateTimeUtil.DateTimeToString8(this.dateControl_start.Value);
            string strEndDate = DateTimeUtil.DateTimeToString8(this.dateControl_end.Value);

            string strWarning = "";

            // 根据日期范围,发生日志文件名
            // parameters:
            //      strStartDate    起始日期。8字符
            //      strEndDate  结束日期。8字符
            // return:
            //      -1  错误
            //      0   成功
            nRet = MakeLogFileNames(strStartDate,
                strEndDate,
                true,
                out LogFileNames,
                out strWarning,
                out strError);
            if (nRet == -1)
                return -1;

            if (String.IsNullOrEmpty(strWarning) == false)
                MessageBox.Show(this, strWarning);

            string strStyle = "";
            if (this.MainForm.AutoCacheOperlogFile == true)
                strStyle = "autocache";

            ProgressEstimate estimate = new ProgressEstimate();

            nRet = OperLogForm.ProcessFiles(this,
stop,
estimate,
Channel,
LogFileNames,
this.MainForm.OperLogLevel,
strStyle,
this.MainForm.OperLogCacheDir,
null,   // param,
procDoRecord,   // DoRecord,
out strError);
            if (nRet == -1)
                return -1;

            return nRet;
        }
Example #5
0
        // const int INSERT_BATCH = 100;  // 300;



        // 根据日志文件创建本地 operlogxxx 表
        int DoCreateOperLogTable(
            long lProgressStart,
            string strStartDate,
            string strEndDate,
            out string strLastDate,
            out long lLastIndex,
            out string strError)
        {
            strError = "";
            strLastDate = "";
            lLastIndex = 0;

            int nRet = 0;

            // strEndDate 里面可能会包含 ":0-99" 这样的附加成分
            string strLeft = "";
            string strEndRange = "";
            StringUtil.ParseTwoPart(strEndDate,
                ":",
                out strLeft,
                out strEndRange);
            strEndDate = strLeft;

            string strStartRange = "";
            StringUtil.ParseTwoPart(strStartDate,
                ":",
                out strLeft,
                out strStartRange);
            strStartDate = strLeft;

            // TODO: start 和 end 都有 range,而且 start 和 end 是同一天怎么办?

            // 删除不必要的索引
            {
                this._connectionString = GetOperlogConnectionString();  //  SQLiteUtil.GetConnectionString(this.MainForm.UserDir, "operlog.bin");

                foreach (string type in OperLogTable.DbTypes)
                {
                    nRet = OperLogTable.DeleteAdditionalIndex(
                        type,
                        this._connectionString,
                        out strError);
                    if (nRet == -1)
                        return -1;
                }
            }

            List<string> filenames = null;

            string strWarning = "";

            // 根据日期范围,发生日志文件名
            // parameters:
            //      strStartDate    起始日期。8字符
            //      strEndDate  结束日期。8字符
            // return:
            //      -1  错误
            //      0   成功
            nRet = OperLogStatisForm.MakeLogFileNames(strStartDate,
                strEndDate,
                true,  // true,
                out filenames,
                out strWarning,
                out strError);
            if (nRet == -1)
                return -1;

            if (String.IsNullOrEmpty(strWarning) == false)
                MessageBox.Show(this, strWarning);

            if (filenames.Count > 0 && string.IsNullOrEmpty(strEndRange) == false)
            {
                filenames[filenames.Count - 1] = filenames[filenames.Count - 1] + ":" + strEndRange;
            }
            if (filenames.Count > 0 && string.IsNullOrEmpty(strStartRange) == false)
            {
                filenames[0] = filenames[0] + ":" + strStartRange;
            }

            this.Channel.Timeout = new TimeSpan(0, 1, 0);   // 一分钟

            using (SQLiteConnection connection = new SQLiteConnection(this._connectionString))
            {
                connection.Open();

                ProgressEstimate estimate = new ProgressEstimate();

                OperLogLoader loader = new OperLogLoader();
                loader.Channel = this.Channel;
                loader.Stop = this.Progress;
                // loader.owner = this;
                loader.estimate = estimate;
                loader.FileNames = filenames;
                loader.nLevel = 2;  //  this.MainForm.OperLogLevel;
                loader.AutoCache = false;
                loader.CacheDir = "";
                loader.Filter = "borrow,return,setReaderInfo,setBiblioInfo,setEntity,setOrder,setIssue,setComment,amerce,passgate,getRes";

                loader.ProgressStart = lProgressStart;

                loader.Prompt -= new MessagePromptEventHandler(loader_Prompt);
                loader.Prompt += new MessagePromptEventHandler(loader_Prompt);

                // List<OperLogLine> circu_lines = new List<OperLogLine>();
                MultiBuffer buffer = new MultiBuffer();
                buffer.Initial();
                OperLogLineBase.MainForm = this.MainForm;

                try
                {
                    int nRecCount = 0;
                    foreach (OperLogItem item in loader)
                    {
                        string strXml = item.Xml;

                        if (string.IsNullOrEmpty(strXml) == true)
                        {
                            nRecCount++;
                            continue;
                        }

                        {
                            XmlDocument dom = new XmlDocument();
                            try
                            {
                                dom.LoadXml(strXml);
                            }
                            catch (Exception ex)
                            {
                                strError = item.Date + " 中偏移为 " + item.Index.ToString() + " 的日志记录 XML 装载到 DOM 时出错: " + ex.Message;
                                DialogResult result = MessageBox.Show(this,
strError + "\r\n\r\n是否跳过此条记录继续处理?",
"ReportForm",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question,
MessageBoxDefaultButton.Button1);
                                if (result == DialogResult.No)
                                    return -1;
                                continue;
                            }

                            string strOperation = DomUtil.GetElementText(dom.DocumentElement, "operation");
#if NO
                                if (strOperation != "borrow" && strOperation != "return")
                                {
                                    nRecCount++;
                                    continue;
                                }
#endif
                            nRet = buffer.AddLine(
                                strOperation,
                                dom,
                                item.Date,
                                item.Index,
                                out strError);
                            if (nRet == -1)
                                return -1;
                            // -2 不要报错
                        }

                        bool bForce = false;
                        if (nRecCount >= 4000)
                            bForce = true;
                        nRet = buffer.WriteToDb(connection,
                            true,
                            bForce,
                            out strError);
                        if (bForce == true)
                        {
                            strLastDate = item.Date;
                            lLastIndex = item.Index + 1;
                            nRecCount = 0;
                        }
                        nRecCount++;
#if NO
                            if (circu_lines.Count >= INSERT_BATCH
    || (circu_lines.Count > 0 && nCircuRecCount >= 1000))
                            {
                                // 写入数据库一次
                                nRet = OperLogLine.AppendOperLogLines(
                                    connection,
                                    circu_lines,
                                    true,
                                    out strError);
                                if (nRet == -1)
                                    return -1;
                                circu_lines.Clear();

                                strLastDate = item.Date;
                                lLastIndex = item.Index + 1;
                                nCircuRecCount = 0;
                            }

                            nCircuRecCount++;
#endif

                    }
                }
                catch (Exception ex)
                {
                    strError = ExceptionUtil.GetDebugText(ex);
                    return -1;
                }

#if NO
                    if (circu_lines.Count > 0)
                    {
                        // 写入数据库一次
                        nRet = OperLogLine.AppendOperLogLines(
                            connection,
                            circu_lines,
                            true,
                            out strError);
                        if (nRet == -1)
                            return -1;

                        // 表示处理完成
                        strLastDate = "";
                        lLastIndex = 0;
                    }
#endif
                nRet = buffer.WriteToDb(connection,
                    true,
                    true,   // false,
                    out strError);
                if (nRet == -1)
                    return -1;

                // 表示处理完成
                strLastDate = "";
                lLastIndex = 0;
            }

            return 0;
        }
Example #6
0
        // 从记录路径文件装载
        /// <summary>
        /// 从记录路径文件装载
        /// </summary>
        /// <param name="strRecPathFilename">记录路径文件名(全路径)</param>
        /// <param name="bClearBefore">是否要在装载前情况浏览列表</param>
        /// <param name="strError">返回出错信息</param>
        /// <returns>-1: 出错,错误信息在 strError 参数返回; 0: 成功</returns>
        public int LoadFromRecPathFile(string strRecPathFilename,
            bool bClearBefore,
            out string strError)
        {
            strError = "";
            int nRet = 0;

            if (bClearBefore == true)
                ClearBefore();

            string strTimeMessage = "";

            StreamReader sr = null;
            try
            {
                // 打开文件
                sr = new StreamReader(strRecPathFilename);

                EnableControls(false);
                // MainForm.ShowProgress(true);

                stop.OnStop += new StopEventHandler(this.DoStop);
                stop.Initial("正在初始化浏览器组件 ...");
                stop.BeginLoop();
                this.Update();
                this.MainForm.Update();

                try
                {
                    // this.m_nGreenItemCount = 0;

                    // 逐行读入文件内容
                    // 测算文件行数
                    int nLineCount = 0;
                    for (; ; )
                    {
                        if (stop != null)
                        {
                            if (stop.State != 0)
                            {
                                strError = "用户中断1";
                                goto ERROR1;
                            }
                        }

                        string strLine = "";
                        strLine = sr.ReadLine();

                        if (strLine == null)
                            break;

                        strLine = strLine.Trim();
                        if (String.IsNullOrEmpty(strLine) == true)
                            continue;

                        // 检查路径所从属书目库是否为图书/期刊库?
                        // return:
                        //      -1  error
                        //      0   不符合要求。提示信息在strError中
                        //      1   符合要求
                        nRet = CheckItemRecPath(this.comboBox_load_type.Text,
                            strLine,
                            out strError);
                        if (nRet == -1)
                            goto ERROR1;
                        if (nRet == 0)
                        {
                            GetErrorInfoForm().WriteHtml(strError + "\r\n");
                        }

                        nLineCount++;
                        // stop.SetMessage("正在装入册条码号 " + strLine + " 对应的记录...");
                    }

                    // 设置进度范围
                    stop.SetProgressRange(0, nLineCount);
                    sr.Close();

                    ProgressEstimate estimate = new ProgressEstimate();
                    estimate.SetRange(0, nLineCount);
                    estimate.Start();

                    List<string> lines = new List<string>();
                    // 正式开始处理
                    sr = new StreamReader(strRecPathFilename);
                    for (int i = 0; ; i++)
                    {
                        if (stop != null)
                        {
                            if (stop.State != 0)
                            {
                                strError = "用户中断1";
                                goto ERROR1;
                            }
                        }

                        string strLine = "";
                        strLine = sr.ReadLine();

                        stop.SetProgressValue(i);

                        if (strLine == null)
                            break;

                        strLine = strLine.Trim();
                        if (String.IsNullOrEmpty(strLine) == true)
                            continue;

                        if (strLine[0] == '#')
                            continue;   // 注释行

                        lines.Add(strLine);
                        if (lines.Count >= 100)
                        {
                            if (lines.Count > 0)
                                stop.SetMessage("(" + i.ToString() + " / " + nLineCount.ToString() + ") 正在装入路径 " + lines[0] + " 等记录。"
                                    + "剩余时间 " + ProgressEstimate.Format(estimate.Estimate(i)) + " 已经过时间 " + ProgressEstimate.Format(estimate.delta_passed));

                            // 处理一小批记录的装入
                            nRet = DoLoadRecords(lines,
                                null,
                                out strError);
                            if (nRet == -1)
                                goto ERROR1;
                            lines.Clear();
                        }
                    }

                    // 最后剩下的一批
                    if (lines.Count > 0)
                    {
                        if (lines.Count > 0)
                            stop.SetMessage("(" + nLineCount.ToString() + " / " + nLineCount.ToString() + ") 正在装入路径 " + lines[0] + " 等记录...");

                        // 处理一小批记录的装入
                        nRet = DoLoadRecords(lines,
                            null,
                            out strError);
                        if (nRet == -1)
                            goto ERROR1;
                        lines.Clear();
                    }

                    strTimeMessage = "共装入册记录 " + nLineCount.ToString() + " 条。耗费时间: " + estimate.GetTotalTime().ToString();
                }
                finally
                {
                    stop.EndLoop();
                    stop.OnStop -= new StopEventHandler(this.DoStop);
                    stop.Initial("装入完成。");
                    stop.HideProgress();

                    EnableControls(true);
                    // MainForm.ShowProgress(false);
                }
            }
            catch (Exception ex)
            {
                strError = ex.Message;
                goto ERROR1;
            }
            finally
            {
                sr.Close();
            }

            this.MainForm.StatusBarMessage = strTimeMessage;

            return 0;
        ERROR1:
            return -1;
        }
Example #7
0
 /// <summary>
 /// 构建文字
 /// </summary>
 /// <param name="lProgressValue">进度量</param>
 /// <returns>文字</returns>
 public string BuildText(long lProgressValue)
 {
     this.Text = "剩余时间 " + ProgressEstimate.Format(this.Estimate(lProgressValue)) + " 已经过时间 " + ProgressEstimate.Format(this.delta_passed);
     return(this.Text);
 }
Example #8
0
        /// <summary>
        /// 刷新若干浏览行
        /// </summary>
        /// <param name="nRecPathColumn">记录路径列的列号</param>
        /// <param name="items">要刷新的行事项数组</param>
        /// <param name="bFillBiblioSummary">是否要填充书目摘要列</param>
        /// <param name="summary_col_names">书目摘要列名数组</param>
        public virtual void RefreshLines(
            int nRecPathColumn,
            List<ListViewItem> items,
            bool bFillBiblioSummary,
            string[] summary_col_names)
        {
            string strError = "";
            string strTimeMessage = "";
            int nRet = 0;

            if (this.InvokeRequired == false)
                EnableControls(false);
            // MainForm.ShowProgress(true);

            stop.OnStop += new StopEventHandler(this.DoStop);
            if (this.InvokeRequired == false)
                stop.Initial("正在刷新 ...");
            stop.BeginLoop();

            try
            {
                if (this.InvokeRequired == false)
                    stop.SetProgressRange(0, items.Count);


                ProgressEstimate estimate = new ProgressEstimate();
                estimate.SetRange(0, items.Count);
                estimate.StartEstimate();

                int nLineCount = 0;
                List<string> lines = new List<string>();
                List<ListViewItem> part_items = new List<ListViewItem>();
                for (int i = 0; i < items.Count; i++)
                {
                    Application.DoEvents();

                    if (stop.State != 0)
                    {
                        strError = "用户中断1";
                        goto ERROR1;
                    }

                    ListViewItem item = items[i];

                    if (this.InvokeRequired == false)
                    {
                        stop.SetMessage("正在刷新 " + item.Text + " ...");
                        stop.SetProgressValue(i);
                    }

                    string strRecPath = ListViewUtil.GetItemText(item, nRecPathColumn);

                    if (string.IsNullOrEmpty(strRecPath) == true)
                        continue;

                    lines.Add(strRecPath);
                    part_items.Add(item);
                    if (lines.Count >= 100)
                    {
                        if (this.InvokeRequired == false)
                        {
                            if (lines.Count > 0)
                                stop.SetMessage("(" + i.ToString() + " / " + nLineCount.ToString() + ") 正在装入路径 " + lines[0] + " 等记录。"
                                    + "剩余时间 " + ProgressEstimate.Format(estimate.Estimate(i)) + " 已经过时间 " + ProgressEstimate.Format(estimate.delta_passed));
                        }

                        // 处理一小批记录的装入
                        nRet = DoLoadRecords(lines,
                            part_items,
                            bFillBiblioSummary,
                            summary_col_names,
                            out strError);
                        if (nRet == -1)
                            goto ERROR1;
                        lines.Clear();
                        part_items.Clear();
                    }
                }

                // 最后剩下的一批
                if (lines.Count > 0)
                {
                    if (this.InvokeRequired == false)
                    {
                        if (lines.Count > 0)
                            stop.SetMessage("(" + nLineCount.ToString() + " / " + nLineCount.ToString() + ") 正在装入路径 " + lines[0] + " 等记录...");
                    }

                    // 处理一小批记录的装入
                    nRet = DoLoadRecords(lines,
                        part_items,
                        bFillBiblioSummary,
                        summary_col_names,
                        out strError);
                    if (nRet == -1)
                        goto ERROR1;
                    lines.Clear();
                    part_items.Clear();
                }

                strTimeMessage = "共刷新册信息 " + nLineCount.ToString() + " 条。耗费时间: " + estimate.GetTotalTime().ToString();
            }
            finally
            {
                stop.EndLoop();
                stop.OnStop -= new StopEventHandler(this.DoStop);
                if (this.InvokeRequired == false)
                {
                    stop.Initial("刷新完成。");
                    stop.HideProgress();
                }

                if (this.InvokeRequired == false)
                    EnableControls(true);
                // MainForm.ShowProgress(false);
            }
            return;
        ERROR1:
            if (this.InvokeRequired == false)
                MessageBox.Show(this, strError);
            else
                stop.SetMessage(strError);
        }
Example #9
0
        // 对每个日志文件,每个日志记录进行循环
        // return:
        //      0   普通返回
        //      1   要全部中断
        int DoTask1Loop(out string strError)
        {
            strError = "";
            int nRet = 0;
            // long lRet = 0;

            List<string> LogFileNames = null;

            // TODO: 是否需要检查起止日期是否为空值?空值是警告还是就当作今天?

            string strStartDate = DateTimeUtil.DateTimeToString8(this.dateControl_start.Value);
            string strEndDate = DateTimeUtil.DateTimeToString8(this.dateControl_end.Value);

            string strWarning = "";

            // 根据日期范围,发生日志文件名
            // parameters:
            //      strStartDate    起始日期。8字符
            //      strEndDate  结束日期。8字符
            // return:
            //      -1  错误
            //      0   成功
            nRet = MakeLogFileNames(strStartDate,
                strEndDate,
                true,
                out LogFileNames,
                out strWarning,
                out strError);
            if (nRet == -1)
                return -1;

            if (String.IsNullOrEmpty(strWarning) == false)
                MessageBox.Show(this, strWarning);

#if NO
            string strStyle = "";
            if (this.MainForm.AutoCacheOperlogFile == true)
                strStyle = "autocache";
#endif

            ProgressEstimate estimate = new ProgressEstimate();

#if NO
            nRet = OperLogForm.ProcessFiles(this,
stop,
estimate,
Channel,
LogFileNames,
this.MainForm.OperLogLevel,
strStyle,
this.MainForm.OperLogCacheDir,
null,   // param,
procDoRecord,   // DoRecord,
out strError);
            if (nRet == -1)
                return -1;
#endif

            OperLogLoader loader = new OperLogLoader();
            loader.Channel = this.Channel;
            loader.Stop = this.Stop;
            loader.owner = this;
            loader.estimate = estimate;
            loader.FileNames = LogFileNames;
            loader.nLevel = this.MainForm.OperLogLevel;
            loader.AutoCache = false;
            loader.CacheDir = "";


            List<OperLogLine> lines = new List<OperLogLine>();

            foreach (OperLogItem item in loader)
            {
                string strXml = item.Xml;

                if (string.IsNullOrEmpty(strXml) == true)
                    continue;

                {
                    XmlDocument dom = new XmlDocument();
                    try
                    {
                        dom.LoadXml(strXml);
                    }
                    catch (Exception ex)
                    {
                        strError = "Load Xml to DOM error: " + ex.Message;
                        return -1;
                    }

                    string strOperation = DomUtil.GetElementText(dom.DocumentElement, "operation");
                    if (strOperation != "borrow" && strOperation != "return")
                        continue;

                    string strAction = DomUtil.GetElementText(dom.DocumentElement, "action");
                    string strOperator = DomUtil.GetElementText(dom.DocumentElement, "operator");

#if NO
                    XmlNode nodeItem = null;
                    string strItemXml = DomUtil.GetElementText(dom.DocumentElement,
                            "itemRecord", out nodeItem);
                    string strItemRecPath = "";
                    if (nodeItem != null)
                        strItemRecPath = DomUtil.GetAttr(nodeItem, "recPath");

                    // 册记录相关的书目记录路径,这个后面统一提取,就不用日志记录中的数据了

#endif
                    XmlNode nodeReader = null;
                    string strReaderXml = DomUtil.GetElementText(dom.DocumentElement,
                            "readerRecord", out nodeReader);
                    string strReaderRecPath = DomUtil.GetAttr(nodeReader, "recPath");
                    string strReaderDbName = Global.GetDbName(strReaderRecPath);
                    // TODO: 根据读者库名获得馆代码
                    string strLibraryCode = "";

                    string strItemBarcode = DomUtil.GetElementText(dom.DocumentElement,
                        "itemBarcode");
                    string strReaderBarcode = DomUtil.GetElementText(dom.DocumentElement,
                        "readerBarcode");
                    string strOperTime = DomUtil.GetElementText(dom.DocumentElement,
                        "operTime");

                    OperLogLine line = new OperLogLine();
                    line.ItemBarcode = strItemBarcode;
                    // 馆藏地点需要另行获得
                    line.ReaderBarcode = strReaderBarcode;
                    line.OperTime = strOperTime;
                    line.LibraryCode = strLibraryCode;

                    lines.Add(line);

                }


                if (lines.Count > 300)
                {
                    // 写入数据库一次

                    lines.Clear();
                }

            }

            if (lines.Count > 0)
            {
                // 写入数据库一次
            }

            return nRet;
        }
Example #10
0
        int LoadOperLogs(List<string> dates,
            out string strError)
        {
            strError = "";

            _operLogItems = new List<OperLogData>();
            _operLogTable = new Hashtable();

            EnableControls(false);
            stop.Style = StopStyle.EnableHalfStop;
            stop.OnStop += new StopEventHandler(this.Channel.DoStop);
            stop.Initial("正在装载日志记录 ...");
            stop.BeginLoop();
            try
            {
                ProgressEstimate estimate = new ProgressEstimate();

                OperLogLoader loader = new OperLogLoader();
                loader.Channel = this.Channel;
                loader.Stop = this.Progress;
                loader.estimate = estimate;
                loader.FileNames = dates;
                loader.Level = 2;  // this.MainForm.OperLogLevel;
                loader.AutoCache = false;
                loader.CacheDir = "";

                loader.Prompt -= new MessagePromptEventHandler(loader_Prompt);
                loader.Prompt += new MessagePromptEventHandler(loader_Prompt);

                foreach (OperLogItem item in loader)
                {
                    if (stop != null && stop.State != 0)
                    {
                        strError = "用户中断";
                        return 0;
                    }

                    if (stop != null)
                        stop.SetMessage("正在获取 " + item.Date + " " + item.Index.ToString() + " " + estimate.Text + "...");

                    if (string.IsNullOrEmpty(item.Xml) == true)
                        continue;


                    XmlDocument dom = new XmlDocument();
                    try
                    {
                        dom.LoadXml(item.Xml);
                    }
                    catch (Exception ex)
                    {
                        strError = "日志记录 " + item.Date + " " + item.Index.ToString() + " XML 装入 DOM 的时候发生错误: " + ex.Message;
                        DialogResult result = MessageBox.Show(this,
    strError + "\r\n\r\n是否跳过此条记录继续处理?",
    "ReportForm",
    MessageBoxButtons.YesNo,
    MessageBoxIcon.Question,
    MessageBoxDefaultButton.Button1);
                        if (result == System.Windows.Forms.DialogResult.No)
                            return -1;

                        // 记入日志,继续处理
                        // this.GetErrorInfoForm().WriteHtml(strError + "\r\n");
                        continue;
                    }

                    string strOperation = DomUtil.GetElementText(dom.DocumentElement, "operation");
                    if (strOperation != "borrow" && strOperation != "return")
                        continue;
                    string strAction = DomUtil.GetElementText(dom.DocumentElement,
        "action");
                    string strOperator = DomUtil.GetElementText(dom.DocumentElement,
        "operator");
                    string strOperTime = DomUtil.GetElementText(dom.DocumentElement,
        "operTime");
                    string strItemBarcode = DomUtil.GetElementText(dom.DocumentElement,
"itemBarcode");
                    string strItemRecPath = "";
                    XmlNode node = dom.DocumentElement.SelectSingleNode("itemRecord/@recPath");
                    if (node == null)
                    {
                        strError = "缺乏 itemRecord 元素的 recPath 属性";
                        continue;
                    }
                    else
                        strItemRecPath = node.Value;

                    OperLogData data = (OperLogData)_operLogTable[strItemRecPath];
                    if (data == null)
                    {
                        data = new OperLogData();
                        data.ItemRecPath = strItemRecPath;
                        _operLogItems.Add(data);
                        _operLogTable[strItemRecPath] = data;
                    }

                    data.ItemBarcode = strItemBarcode;
                    data.Action = strAction;
                    data.Operator = strOperator;
                    data.OperTime = SQLiteUtil.GetLocalTime(strOperTime);
                    data.OperCount++;
                }

                return 0;
            }
            catch (Exception ex)
            {
                strError = "获取日志记录的过程中出现异常: " + ex.Message;
                return -1;
            }
            finally
            {
                stop.EndLoop();
                stop.OnStop -= new StopEventHandler(this.Channel.DoStop);
                stop.Initial("");
                stop.Style = StopStyle.None;

                EnableControls(true);
            }

        }
Example #11
0
        // 上传文件到到 dp2lbrary 服务器
        // parameters:
        //      timestamp   时间戳。如果为 null,函数会自动根据文件信息得到一个时间戳
        //      bRetryOverwiteExisting   是否自动在时间戳不一致的情况下覆盖已经存在的服务器文件。== true,表示当发现时间戳不一致的时候,自动用返回的时间戳重试覆盖
        // return:
        //		-1	出错
        //		0   上传文件成功
        int UploadFile(
            Stop stop,
            LibraryChannel channel,
            string strClientFilePath,
            string strServerFilePath,
            string strStyle,
            byte[] timestamp,
            bool bRetryOverwiteExisting,
            out string strError)
        {
            strError = "";

            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-" + (fi.Length - 1).ToString();

                // 按照100K作为一个chunk
                // TODO: 实现滑动窗口,根据速率来决定chunk尺寸
                ranges = RangeList.ChunkRange(strRange,
                    channel.UploadResChunkSize // 500 * 1024
                    );
            }

            if (timestamp == null)
                timestamp = FileUtil.GetFileTimestamp(strClientFilePath);

            byte[] output_timestamp = null;

            // REDOWHOLESAVE:
            string strWarning = "";

            bool bCharRedo = false; // 是否正在击键重做的过程中

            TimeSpan old_timeout = channel.Timeout;

            channel.Timeout = TimeSpan.FromSeconds(10);

            int nCursorLeft = Console.CursorLeft;
            int nCursorTop = Console.CursorTop;

            ProgressEstimate _estimate = new ProgressEstimate();

            _estimate.SetRange(0, fi.Length);
            _estimate.StartEstimate();

            string strTotalSize = GetSizeString(fi.Length);

            try
            {
                for (int j = 0; j < ranges.Length; j++)
                {
                    if (stop != null && stop.State != 0)
                    {
                        strError = "用户中断";
                        goto ERROR1;
                    }

                    RangeList rl = new RangeList(ranges[j]);
                    long uploaded = ((RangeItem)rl[0]).lStart;

                    string strPercent = "";
                    if (rl.Count >= 1)
                    {
                        double ratio = (double)uploaded / (double)fi.Length;
                        strPercent = String.Format("{0,3:N}", ratio * (double)100) + "%";
                    }

                    string strUploadedSize = GetSizeString(uploaded);


                    string strWaiting = "";
                    if (j == ranges.Length - 1)
                    {
                        strWaiting = " please wait ...";
                        channel.Timeout = new TimeSpan(0, 40, 0);   // 40 分钟
                    }
                    else if (j > 0)
                        strWaiting = "剩余时间 " + ProgressEstimate.Format(_estimate.Estimate(uploaded)) + " 已经过时间 " + ProgressEstimate.Format(_estimate.delta_passed);

#if NO
                    if (stop != null)
                        stop.SetMessage( // strMessagePrefix + 
                            "正在上载 " + ranges[j] + "/"
                            + Convert.ToString(fi.Length)
                            + " " + strPercent + " " + strClientFilePath + strWarning + strWaiting);
#endif
                    ProgressMessage(nCursorLeft, nCursorTop,
                        "uploading "
                        // + ranges[j] + "/"  + Convert.ToString(fi.Length)
                        + " " + strPercent + " " 
                        + strUploadedSize + "/" + strTotalSize + " "
                        // + strClientFilePath
                        + strWarning + strWaiting);
                    int nRedoCount = 0;
                REDO:
                    long lRet = channel.SaveResObject(
                        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
                            && channel.ErrorCode == DigitalPlatform.LibraryClient.localhost.ErrorCode.TimestampMismatch
                            && nRedoCount == 0)
                        {
                            nRedoCount++;
                            goto REDO;
                        }

                        if (channel.ErrorCode == DigitalPlatform.LibraryClient.localhost.ErrorCode.TimestampMismatch
                            && bCharRedo == true)
                        {
                            bCharRedo = false;
                            goto REDO;
                        }

                        Console.WriteLine("出错: " + strError + "\r\n\r\n是否重试? (Y/N)");
                        ConsoleKeyInfo info = Console.ReadKey();
                        if (info.KeyChar == 'y' || info.KeyChar == 'Y')
                        {
                            Console.WriteLine();
                            nCursorLeft = Console.CursorLeft;
                            nCursorTop = Console.CursorTop + 2;
                            bCharRedo = true;
                            goto REDO;
                        }
                        goto ERROR1;
                    }

                    bCharRedo = false;
                }
            }
            finally
            {
                channel.Timeout = old_timeout;

                ProgressMessage(nCursorLeft, nCursorTop, "");
            }

            return 0;
        ERROR1:
            return -1;
        }