Как упоминал Игорь в комментариях (и возвращаясь к теме вопроса), вы можете читать большой двоичный файл в кусках и записывать на диск по одному фрагменту за раз. Это уменьшит объем вашей памяти за счет замедления из-за дополнительных операций ввода-вывода диска.
Как правило, для потоковых потоков может быть сложнее обрезать, поскольку вы можете завершить фрагмент с неполным сообщением (если ваша точка фрагмента была произвольной, а сообщения были переменной шириной), однако в вашем случае у вас, кажется, есть сообщения с фиксированной шириной, поэтому конечные точки куска легче рассчитать.
В любом случае, мне часто полезно использовать цикл (/) и отслеживать свой последний известный (хороший) индекс, а затем начинать с этого индекса при чтении следующего фрагмента. Общая идея (непроверенная) была бы чем-то вроде
file:`:/q/data/Q200405A.BIN;
chunkrows:10000; /number of rows to process in each chunk
columns:`QTIM`BID`OFR`QSEQ`QFRSIZ`OFRSIZ`MODE`EX`MMID;
types:"ijjiiihcs";
widths:4 8 8 4 4 4 2 1 4;
{
data:flip columns!(types;widths)1:(file;x;chunkrows*sum widths);
upsertToDisk[data]; /write a function to upsert to disk (partitioned or splayed)
x+chunkrows*sum widths /return the rolling index of the starting point for the next chunk
}/[hcount[file]>;0]
Это будет продолжаться до тех пор, пока последний хороший индекс не достигнет конца файла. Вы можете отрегулировать размер селектора соответственно в зависимости от ограничений памяти.
В конечном счете, если вы пытаетесь обрабатывать большие данные с бесплатной 32-битной версией, тогда у вас будут головные боли, независимо от того, что вы делаете.
Вы используете 32-битный kdb +? –
Да. Это единственная версия, доступная здесь: https://kx.com/software-download.php –
В этом случае вы не можете многое сделать, я боюсь. Из-за естественного ограничения 32-битного процесса он не может адресовать более 4 ГБ (на самом деле это всего 2 ГБ на Windows), и размер вашего набора данных, вероятно, достигает этого предела. –