3

n 個の「レコード」を含む大きなファイル (Mathematica で作成) があり、これらの各レコードは固定長 m のリストであり、n > 10,000 および 500 < m < 600 (バイト) です。私のシステムには、すべてのレコードをメモリに保持する容量がないことに注意してください。これは、それらをファイルに書き込む理由です。これらのレコードを逆の順序で処理する必要がある (Mathematica の) アプリケーションがあります。つまり、最後に書き出されたレコードが最初に処理されるレコードになります。これらのレコードをファイルから逆順に読み取るにはどうすればよいですか?

その間(Mathematica I/Oで試行錯誤した後)、1つの解決策を見つけました。これは可能な解決策の簡略化された例であることに注意してください。

    fname = "testfile";

    strm = OpenWrite[fname];
    n = 10; (* In general, n could be very large *)
    For[k = 1, k <= n, k++,
      (* Create list on each pass through this loop ... *)

      POt = {{k, k + 1}, {k + 2, k + 3}};
      Print[POt];

      (* Save to a file *)
      Write[strm, POt];
    ];
    Close[strm];

    (* 2nd pass to get byte offsets of each record written to file *)
    strm = OpenRead[fname];
    ByteIndx = {0};
    For[i = 1, i <= n, i++,
      PIn = Read[strm];
      AppendTo[ByteIndx, StreamPosition[strm]];
    ];
    Drop[ByteIndx, -1]

    (* Read records in reverse order *)
    For[i = n, i >= 1, i--,
      SetStreamPosition[strm, ByteIndx[[i]]];
      PIn = Read[strm];
      Print[PIn];

      (* Process PIn ... *)

    ];
    Close[strm];

2 番目のパス (バイト オフセットを取得するため) を省略できればいいのですが、これを行う方法はまだわかりません... また、これらのバイト オフセットをファイルに書き込むこともできます (レコードの処理方法と同様)。 )、メモリの問題がまだ残っている場合は、一度に 1 つずつ読み戻します。

4

1 に答える 1

0

答えを出すために、2 番目のパスを簡潔に書くことができます。

strm = OpenRead[fname];
ByteIndx=Reap[While[Sow[StreamPosition[strm]]; !TrueQ[Read[strm ] == EndOfFile]]][[2,1,;;-2]]
n=Length[ByteIndx]
于 2013-02-14T18:49:17.130 に答える