2009-05-31 3 views
8

Iそのテキストファイルlines.Inside 25kを持つ巨大なテキストファイルを持っているそれぞれの行は、 "1 \トン(行番号)" で始まるTextReader/StreamReaderに「go to line」オプションがありますか?

例:

1 1 ITEM_ETC_GOLD_01 골드(소) xxx xxx xxx_TT_DESC 0 0 3 3 5 0 180000 3 0 1 0 0 255 1 1 0 0 0 0 0 0 0 0 0 0 -1 0 -1 0 -1 0 -1 0 -1 0 0 0 0 0 0 0 100 0 0 0 xxx item\etc\drop_ch_money_small.bsr xxx xxx xxx 0 2 0 0 1 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 0 0 0 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1 표현할 골드의 양(param1이상) -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx 0 0 
1 2 ITEM_ETC_GOLD_02 골드(중) xxx xxx xxx_TT_DESC 0 0 3 3 5 0 180000 3 0 1 0 0 255 1 1 0 0 0 0 0 0 0 0 0 0 -1 0 -1 0 -1 0 -1 0 -1 0 0 0 0 0 0 0 100 0 0 0 xxx item\etc\drop_ch_money_normal.bsr xxx xxx xxx 0 2 0 0 1 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 0 0 0 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1000 표현할 골드의 양(param1이상) -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx 0 0 
1 3 ITEM_ETC_GOLD_03 골드(대) xxx xxx xxx_TT_DESC 0 0 3 3 5 0 180000 3 0 1 0 0 255 1 1 0 0 0 0 0 0 0 0 0 0 -1 0 -1 0 -1 0 -1 0 -1 0 0 0 0 0 0 0 100 0 0 0 xxx item\etc\drop_ch_money_large.bsr xxx xxx xxx 0 2 0 0 1 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 0 0 0 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 10000 표현할 골드의 양(param1이상) -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx 0 0 
1 4 ITEM_ETC_HP_POTION_01 HP 회복 약초 xxx SN_ITEM_ETC_HP_POTION_01 SN_ITEM_ETC_HP_POTION_01_TT_DESC 0 0 3 3 1 1 180000 3 0 1 1 1 255 3 1 0 0 1 0 60 0 0 0 1 21 -1 0 -1 0 -1 0 -1 0 -1 0 0 0 0 0 0 0 100 0 0 0 xxx item\etc\drop_ch_bag.bsr item\etc\hp_potion_01.ddj xxx xxx 50 2 0 0 1 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 0 0 0 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 120 HP회복양 0 HP회복양(%) 0 MP회복양 0 MP회복양(%) -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx 0 0 
1 5 ITEM_ETC_HP_POTION_02 HP 회복약 (소) xxx SN_ITEM_ETC_HP_POTION_02 SN_ITEM_ETC_HP_POTION_02_TT_DESC 0 0 3 3 1 1 180000 3 0 1 1 1 255 3 1 0 0 1 0 110 0 0 0 2 39 -1 0 -1 0 -1 0 -1 0 -1 0 0 0 0 0 0 0 100 0 0 0 xxx item\etc\drop_ch_bag.bsr item\etc\hp_potion_02.ddj xxx xxx 50 2 0 0 2 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 0 0 0 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 220 HP회복양 0 HP회복양(%) 0 MP회복양 0 MP회복양(%) -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx 0 0 
1 6 ITEM_ETC_HP_POTION_03 HP 회복약 (중) xxx SN_ITEM_ETC_HP_POTION_03 SN_ITEM_ETC_HP_POTION_03_TT_DESC 0 0 3 3 1 1 180000 3 0 1 1 1 255 3 1 0 0 1 0 200 0 0 0 4 70 -1 0 -1 0 -1 0 -1 0 -1 0 0 0 0 0 0 0 100 0 0 0 xxx item\etc\drop_ch_bag.bsr item\etc\hp_potion_03.ddj xxx xxx 50 2 0 0 3 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 0 0 0 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 370 HP회복양 0 HP회복양(%) 0 MP회복양 0 MP회복양(%) -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx 0 0 
1 7 ITEM_ETC_HP_POTION_04 HP 회복약 (대) xxx SN_ITEM_ETC_HP_POTION_04 SN_ITEM_ETC_HP_POTION_04_TT_DESC 0 0 3 3 1 1 180000 3 0 1 1 1 255 3 1 0 0 1 0 400 0 0 0 7 140 -1 0 -1 0 -1 0 -1 0 -1 0 0 0 0 0 0 0 100 0 0 0 xxx item\etc\drop_ch_bag.bsr item\etc\hp_potion_04.ddj xxx xxx 50 2 0 0 4 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 0 0 0 0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 570 HP회복양 0 HP회복양(%) 0 MP회복양 0 MP회복양(%) -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx 0 0 

質問:どのように私は直接読み取るか、について例、行5?

答えて

10

あなたはIEnumerable<string>を実装して、LINQを使用するように私のLineReaderクラス(MiscUtilで1かsimple version hereのいずれか)を使用することができます。

string line5 = new LineReader(file).Skip(4).First(); 

これは確かに、.NET 3.5を想定しています。そうでない場合は、TextReader(例:File.OpenText)を開き、ReadLine()を4回呼び出して不要な行をスキップしてから、もう一度5行目を読みます。

各行に正確なバイト数がわからない限り、これを「ショートカット」する方法はありません。

+0

あなたが望む行に到達するまで、行ごとに読み込まれるフードの下にあります。直接5行目に行く方法はありますか? – BFree

+2

Streamは、事前に5行目のバイトオフセットBFreeを知っていますか? –

+0

LineReaderにStreamコンストラクタのオーバーロードがない理由はありますか?Func ? –

3

固定幅のデータ形式(すべての行が同じ長さであることがわかっている)を扱う場合は、長さに目的の行番号を掛け、Stream.Seekを使用して開始点を見つけることができますn番目の行の

行が固定長でない場合は、必要な行の先頭になるまで、正しい改行数を見つける必要があります。それはStreamReader.ReadLineで最も簡単に行えます。 (Jon Skeetの示唆しているように、拡張メソッドを使用してファイルをIEnumerable <の文字列>にすることができます。これにより、より良い構文が得られますが、あなたはReadLineを使用します)。

パフォーマンスが問題である場合は、それが(少し)より効率的な手動Stream.Readメソッドを使用して、ファイル内<CR> <LF>バイト配列をスキャンするかもしれません。私はそれをテストしていません。しかし、StreamReaderは、明らかにバイトシーケンスから文字列を構築するために何らかの作業を行う必要があります。最初の行を気にしなければ、この作業は保存できます。理論的には、より良い実行方法。しかし、これはあなたのためにはるかに多くの仕事になるでしょう。

+0

行は固定長ではありませんが、各行の長さを見つけることができます。ただし、25,000行の大きなファイルの各行を読み込むのには時間がかかります。 –

+0

5行目に行く場合は、すべての行を読む必要はありません。 –

+0

各行の長さがわからない場合は、各行を実行する以外の方法はありません特定の行を見つけるために、ある方法または別の方法で。魔法のショートカットはありません。これが追加されるファイルで、新しいデータを処理する必要がある場合は、最後のバイトオフセットを読み込み間に格納し、次の読み込み時にそこから開始することができます。 – driis

3

すべての行が固定幅で、固定幅のエンコーディングを使用している場合(つまり、現在最も一般的なものの1つであるUTF-8ではなく)、テキストファイルの行に直接ジャンプすることはできません。

唯一の方法は、行を読み取って不要な行を破棄することです。

また、(たとえば)1000行目がバイトオフセット[x]で始まり、2000行目がバイトオフセット[y]で始まることを示す索引をファイルの上端(または外部ファイル) ]など。FileStream.Positionまたは.Seek()を使用して、最も近いインデックスポイントに移動し、前方に移動します。

最も単純なアプローチ(インデックスなし)を想定すると、Jonの例のコードは正常に動作するはずです。あなたは(というだけでラインインデックスよりも)行の値をテストする必要がある場合は、それは簡単です

// to read multiple lines in a block 
public static IEnumerable<string> ReadLines(
     string path, int lineIndex, int count) { 
    if (string.IsNullOrEmpty(path)) throw new ArgumentNullException("path"); 
    if (lineIndex < 0) throw new ArgumentOutOfRangeException("lineIndex"); 
    if (count < 0) throw new ArgumentOutOfRangeException("count"); 
    using (StreamReader reader = File.OpenText(path)) { 
     string line; 
     while (count > 0 && (line = reader.ReadLine()) != null) { 
      if (lineIndex > 0) { 
       lineIndex--; // skip 
       continue; 
      } 
      count--; 
      yield return line; 
     } 
    } 
} 
// to read a single line 
public static string ReadLine(string path, int lineIndex) { 
    foreach (string line in ReadLines(path, lineIndex, 1)) { 
     return line; 
    } 
    throw new IndexOutOfRangeException(); 
} 

:あなたはLINQをしたくない場合は、.NET 2.0 +で似たようなC#2.0をノックすることができますあまりにもそうするには十分です。イテレータブロックを微調整するだけです。

1

ファイルから多くの異なる行を検索する場合(すべてではないが)、索引を作成することでいくつかの利点が得られるかもしれません。すでにここにある提案を使用してください。しかし、あなたが進んでいくにつれて、既に見つかった行のバイトオフセットの配列を構築して、そのたびに最初からファイルを再スキャンすることを防ぐことができます。

補遺:
ありますが、時折「ランダム」行が必要な場合は、あなたが速いそれを行うことができますもう一つの方法があるが、より複雑な検索(の費用でJonの答えは十分に速い場合、私は」簡単にするために間違いなくそれに固執する)。

「バイナリ検索」を実行することができます。ファイルの途中から「1」という文字列を探し始めると、見つかった最初のオカレンスがどの行番号であるかを知ることができます。あなたが探している行が見つかった番号との相対的な位置に基づいて、あなたは再帰的に分割し続けます。

さらにパフォーマンスを向上させるには、線の長さがおおよそ同じで、ファイル内の行の総数に対する探している線のおおよその位置を「推測」するアルゴリズムを持つこともできますそこからこの検索を実行します。ファイルの長さを仮定したくない場合は、最初に半分に分割するだけで自己プライムにすることもできますし、行番号を使ってファイル内の行数を近似します全体。

明らかに実装するのは簡単ではありませんが、多数の行を含むファイルにランダムアクセスが多い場合は、パフォーマンスが向上します。

0

ReadLine()をバックグラウンドで使用する関数を使用して24,000行目にジャンプする必要がある場合は、少し遅くなります。

行番号が高い場合は、ファイル内のどこに行があるのか​​を知り、そこから読み始めたいと思うかもしれません。 24,567行目に行くには、最初に24,566行を読む必要はありません。真ん中のどこかにスキップして、/ tの後の数字に基づいてあなたがどの行にいるのかを調べ、そこから数えることができます。

私は、RDBMSの前にDBを構築しなければならなかった開発者と仕事をしていました。あなたの問題に対する彼の解決策は、私が書いたことと似ていましたが、彼の場合、別のファイルにマップを保管していました。マップは、ドキュメント内のその位置に100行ごとにマップすることができます。このようなマップは非常に迅速に読み込むことができ、読み込み時間が長くなる可能性があります。 彼のシステムは非常に速く、読み取り専用のデータに対しては効率的でしたが、読み取り/書き込みのデータにはあまり適していませんでした。 (マップ全体を変更しなければならないたびに、これはあまり効率的ではありません)

関連する問題