/// <summary> /// ディスクにキャッシュしながらレスを読み込む /// </summary> /// <param name="resSets"></param> /// <param name="byteParsed">解析された総バイト数が格納される</param> /// <returns>読み込まれたバイト数を返す</returns> public override int Read(ResSetCollection resSets, out int byteParsed) { if (!isOpen) { throw new InvalidOperationException("ストリームが開かれていません"); } byteParsed = 0; ResSetCollection tempCollection = new ResSetCollection(); int byteCount = 0; int writeCount = 0; // キャッシュを読む if (storage.IsOpen && storage.CanRead) { byteCount = storage.Read(tempCollection, out byteParsed); tempCollection.IsNew = false; // データがなければキャッシュストリームは閉じる if (byteCount == 0) { storage.Close(); OnCacheComplete(this, new EventArgs()); OpenBaseStream(headerInfo); } } // キャッシュがなければ実際に基本ストリームから読み込む if (baseReader.IsOpen) { byteCount = baseReader.Read(tempCollection, out byteParsed); tempCollection.IsNew = true; // あぼーんがあった場合、処理を中止。 if (byteCount == -1) { return(-1); } try { if (storage.IsOpen) { writeCount = storage.Write(tempCollection); } } finally { headerInfo.GotByteCount += byteParsed; headerInfo.GotResCount += tempCollection.Count; headerInfo.NewResCount += tempCollection.Count; } } resSets.AddRange(tempCollection); position += byteCount; return(byteCount); }
/// <summary> /// 単独のdatファイル開き、を既得キャッシュとして保存 /// </summary> /// <param name="cache"></param> /// <param name="target">単独のdatと関連づける板</param> /// <param name="filePath">datファイルのファイルパス</param> /// <param name="datNumber">dat番号</param> /// <param name="gzip">datファイルがgzip圧縮されていればtrue、そうでなければfalseを指定する</param> /// <returns>キャッシュされたスレッドのヘッダ情報を返す</returns> public static ThreadHeader OpenDat(Cache cache, BoardInfo target, string filePath, string datNumber, bool gzip) { // ヘッダー情報を作成 ThreadHeader header = TypeCreator.CreateThreadHeader(target.Bbs); header.BoardInfo = target; header.Key = datNumber; header.UseGzip = gzip; header.Subject = String.Empty; ResSetCollection resItems = new ResSetCollection(); using (Stream stream = StreamCreator.CreateReader(filePath, gzip)) { X2chThreadParser parser = new X2chThreadParser(); byte[] buffer = new byte[4096]; bool first = true; int offset = 0, read, parsed; do { // バッファに読み込む read = stream.Read(buffer, 0, buffer.Length); offset += read; // 解析しResSet構造体の配列を作成 ResSet[] array = parser.Parse(buffer, read, out parsed); resItems.AddRange(array); // スレタイを取得しておく if (first && array.Length > 0) { header.Subject = array[0].Tag as String; first = false; } } while (read != 0); // 既得バイト数とレス数を設定 header.GotByteCount = offset; header.GotResCount = resItems.Count; } // datファイルの最終更新日を取得 header.LastModified = File.GetLastWriteTime(filePath); // 読み込んだレスをキャッシュとして保存 using (LocalThreadStorage storage = new LocalThreadStorage(cache, header, StorageMode.Write)) { storage.Write(resItems); } // インデックス情報を生成 ThreadIndexer.Write(cache, header); return(header); }