ReadList
-based post-processing solution
Here is a solution which doesn't require reading the file twice (inspired by this answer by Mr.Wizard):
read[s_String] := # &[ReadList[#, Number, RecordLists -> True], Close[#]] &@
StringToStream[s];
data2 = ReadList["test00.txt", read[Record], RecordSeparators -> "\n\n"]; //
AbsoluteTiming // First
0.276596
(the file "test00.txt"
contains 71641 lines from which 7201 are single blank lines).
The above method ignores repeated blank lines in our input file with blank line separated datasets. This means that if adjacent datasets are separated by more than one blank line, we won't get an empty dataset {}
in the resulting list. To the contrary, the method by george2079 will put empty lists {}
between successive blank lines.
On my machine the above method is even more efficient than the method by george2079. The following is an improved and optimized version of his solution with no assumptions about how many numbers must be on each line and with proper handling of files without blank line at the end:
(data = Module[{f = OpenRead["test00.txt"], vals, breaks, data, i = 0},
vals = ReadList[f, Number, RecordLists -> True];
SetStreamPosition[f, 1];
breaks =
Flatten[{0, Position[#, ""], Length[#] + 1}] &@
ReadList[f, Record, NullRecords -> True];
If[breaks[[-1]] == breaks[[-2]] + 1, breaks = Most[breaks]];
data = Table[Take[vals, {i + 1, i += n}], {n, Differences[breaks] - 1}];
Close[f]; data]) // AbsoluteTiming // First
0.313066
(for efficient construction of the ragged array I used the method from this answer by Mr.Wizard).
Without repeated blank lines the results are identical:
data2 == data
True
If the input file contains repeated blank lines, the results will be identical after removing empty lists {}
:
data2 == DeleteCases[data, {}]
True
String-manipulation pre-processing approach
(data3 = Get[#]; Close[#];) &@
StringToStream@
StringReplace[
Import["test00.txt", "Text"], {StartOfString -> "{{{", "\n\n" -> "}},{{",
"\n" -> "},{", (" " | "\t") .. -> ",", EndOfString -> "}}}"}] //
AbsoluteTiming // First
0.64618
data2 == data3 //. {} -> Nothing
True