/// <summary> /// 插入資訊 /// </summary> /// <param name="series">SeriesSymbolData 類別</param> /// <param name="date">欲插入的日期(資料會被插入至該指定的日期前)</param> internal void Insert(SeriesSymbolData series, DateTime date) { try { string sFile = string.Format("{0}\\{1}\\{2}", __sPath, (series.DataRequest.Resolution.TotalSeconds < Resolution.MAX_BASE_TOTALSECONDS) ? "mins" : "days", series.DataRequest.Symbol); using (FileStream cStream = new FileStream(sFile, (__bCreate) ? FileMode.Create : FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite)) { bool bFind = false; if (!__bCreate) { long lCount = cStream.Length / MAX_BLOCK_SIZE; bFind = FileSearchUtil.BinaryNearSearch(cStream, lCount, MAX_BLOCK_SIZE, date); } if (bFind) { long lCurrentP = cStream.Position; //先保留後面的資料以便插入時不會被覆蓋 long lRevSize = cStream.Length - lCurrentP; ZBuffer cTemp = new ZBuffer((int)lRevSize); cStream.Read(cTemp.Data, 0, (int)lRevSize); cTemp.Length = (int)lRevSize; cStream.SetLength(lCurrentP + 1); cStream.Position = lCurrentP; //移動置固定位置 ZBuffer cBuffer = new ZBuffer(64); int iHistoryIndex = series.Indexer.HistoryIndex; int iCount = series.Count; for (int i = 0; i < iCount; i++) { int iIndex = iHistoryIndex + i; cBuffer.Length = 0; cBuffer.Add(series.Time[iIndex]); cBuffer.Add(series.Open[iIndex]); cBuffer.Add(series.High[iIndex]); cBuffer.Add(series.Low[iIndex]); cBuffer.Add(series.Close[iIndex]); cBuffer.Add(series.Volume[iIndex]); cStream.Write(cBuffer.Data, 0, cBuffer.Length); } cStream.Write(cTemp.Data, 0, cTemp.Length); //再將後面的資料合併 } } if (logger.IsInfoEnabled) { logger.InfoFormat("[FileWrite] {0} insert completed... count={1}", sFile, series.Count); } } catch (Exception __errExcep) { if (logger.IsErrorEnabled) { logger.ErrorFormat("[FileWrite] '{0}' insert error...", series.DataRequest.Symbol, series.Count); } if (logger.IsErrorEnabled) { logger.ErrorFormat("{0}/r/n{1}", __errExcep.Message, __errExcep.StackTrace); } } }
public void ProcessRequest(HttpContext context) { HttpResponse cResponse = context.Response; cResponse.ContentType = "application/octet-stream"; HttpRequest cRequest = context.Request; string sExchange = cRequest.Form["exchange"]; //交易所簡稱 string sSymbolId = cRequest.Form["symbolId"]; //商品代號 int iTimeFrame = int.Parse(cRequest.Form["timeFrame"]); //時間週期(60=1分, 300=5分) long lPosition = long.Parse(cRequest.Form["position"]); //客戶端目前歷史資料的檔案位置 DateTime cStartDate = DateTime.Parse(cRequest.Form["startDate"]); //資料起始時間 DateTime cEndDate = DateTime.Parse(cRequest.Form["endDate"]); //資料結束時間 int iCount = int.Parse(cRequest.Form["count"]); //資料請求個數 string sTimeFrameFormat = (iTimeFrame < DAY_TIMEFRAME_FORMAT) ? "mins" : "days"; string sFilename = context.Server.MapPath(string.Format("~/data/{0}/{1}/{2}", sExchange, sTimeFrameFormat, sSymbolId)); if (File.Exists(sFilename)) { using (FileStream cStream = new FileStream(sFilename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { try { long lStartPosition = 0, lEndPosition = lPosition * DATA_BLOCK_SIZE; int iBlockCount = (int)(cStream.Length / DATA_BLOCK_SIZE); iCount = ((iCount < iBlockCount) ? iCount : iBlockCount); if (iCount == 0) { if (lPosition == -1) { FileSearchUtil.BinaryNearSearch(cStream, iBlockCount, DATA_BLOCK_SIZE, cEndDate.AddSeconds(86400)); lEndPosition = cStream.Position; } FileSearchUtil.BinaryNearSearch(cStream, iBlockCount, DATA_BLOCK_SIZE, cStartDate); lStartPosition = cStream.Position; iCount = (int)((lEndPosition - lStartPosition) / DATA_BLOCK_SIZE); } else { if (lPosition == -1) { FileSearchUtil.BinaryNearSearch(cStream, iBlockCount, DATA_BLOCK_SIZE, cEndDate.AddSeconds(86400)); lEndPosition = cStream.Position; } lStartPosition = lEndPosition - iCount * DATA_BLOCK_SIZE; lStartPosition = (lStartPosition < 0) ? 0 : lStartPosition; iCount = (int)((lEndPosition - lStartPosition) / DATA_BLOCK_SIZE); } lPosition = lStartPosition / DATA_BLOCK_SIZE; int iSize = iCount * DATA_BLOCK_SIZE; byte[] bData = new byte[iSize]; cStream.Position = lStartPosition; iSize = cStream.Read(bData, 0, iSize); int iBeginDate = BitConverter.ToInt32(bData, 0); //起始日期 int iEndDate = BitConverter.ToInt32(bData, iSize - DATA_BLOCK_SIZE); //終止日期 cResponse.Cookies.Add(new HttpCookie("result", INFORMATION_SUCCESS.ToString())); cResponse.Cookies.Add(new HttpCookie("position", lPosition.ToString())); cResponse.Cookies.Add(new HttpCookie("count", iCount.ToString())); cResponse.Cookies.Add(new HttpCookie("dataSize", iSize.ToString())); cResponse.Cookies.Add(new HttpCookie("beginDate", iBeginDate.ToString())); cResponse.Cookies.Add(new HttpCookie("endDate", iEndDate.ToString())); Stream cOutput = cResponse.OutputStream; cOutput.Write(bData, 0, iSize); cOutput.Flush(); } catch { cResponse.Cookies.Add(new HttpCookie("result", ERROR_EXCEPTION.ToString())); } } } else { cResponse.Cookies.Add(new HttpCookie("result", ERROR_FILE_NOT_FOUND.ToString())); } }