Я делаю некоторые необычные манипуляции с данными. У меня есть 36 000 входных файлов. Одновременно в память может быть загружено больше. Я хочу взять первый байт каждого файла и поместить его в один выходной файл, а затем сделать это снова для второго и так далее. Это не нужно делать в каком-то определенном порядке. Поскольку входные файлы сжаты, их загрузка занимает немного больше времени, и они не могут быть прочитаны по одному байту за раз. Я получаю массив байтов каждого входного файла.
Входные файлы имеют размер около ~ 1-6 МБ без сжатия и ~ 0,3-1 МБ со сжатием (сжатие с потерями). Выходные файлы в конечном итоге представляют собой количество входных файлов в байтах. ~ 36 КБ в моем примере.
Я знаю, что ulimit можно установить в ОС Linux, и то же самое можно сделать в Windows. Несмотря на то, что это число может быть увеличено, я не думаю, что какой-либо ОС понравится, когда миллионы файлов записываются одновременно.
Мое текущее решение состоит в том, чтобы создать 3000 или около того потоков буферизованной записи и загружать каждый входной файл по очереди и записывать 1 байт в 3000 файлов, а затем закрывать файл и загружать следующий ввод. В этой системе каждый входной файл нужно открывать примерно 500 раз.
Вся операция занимает 8 дней и является лишь тестовым примером для более практичного приложения, которое в конечном итоге будет иметь большие входные файлы, большее их количество и большее количество выходных файлов.
Захват всех сжатых файлов в памяти, а затем их распаковка по мере необходимости не кажется практичным и не будет масштабироваться для больших входных файлов.
Я думаю, что решение будет состоять в том, чтобы буферизовать то, что я могу из входных файлов (потому что ограничения памяти не позволят буферизовать все это), а затем последовательно записывать в файлы, а затем делать это снова и снова.
Однако я не знаю, есть ли лучшее решение, использующее то, о чем я не читал.
EDIT Я благодарен за быстрый ответ. Я знаю, что был расплывчатым в применении того, что я делаю, и я постараюсь исправить это. В основном у меня есть трехмерный массив [images][X][Y]. Я хочу перебирать каждое изображение и сохранять каждый цвет из определенного пикселя на каждом изображении и делать это для всех изображений. Проблема в ограничении памяти.
byte[] пикселей = ((DataBufferByte) ImageIO.read(fileList.get(k)).getRaster().getDataBuffer()).getData();
Это то, что я использую для загрузки изображений, потому что оно заботится о распаковке и пропуске заголовка.
Я не редактирую его как видео, потому что мне нужно было бы получить кадр, затем превратить его в изображение (дорогостоящее преобразование цветового пространства), а затем преобразовать его в byte[] только для того, чтобы получить данные о пикселях в цветовом пространстве RGB.
Я мог бы загрузить каждое изображение и разделить его на ~ 500 частей (размер Y) и записать в отдельные файлы, которые я оставляю открытыми, и записываю для каждого изображения. Выходы были бы легко под гиг. Полученный файл можно было полностью загрузить в память и превратить в массив для последовательной записи в файл.
Промежуточные шаги означают, что я могу разделить нагрузку на сеть, но я пытаюсь сделать это на ноутбуке низкого качества с 4 ГБ оперативной памяти, без графического процессора и i7 низкого качества.
Я не думал о сохранении чего-либо в файл в качестве промежуточного шага, прежде чем читать ответ Давидбака. Размер - единственное, что делает эту проблему нетривиальной, и теперь я вижу, что размер можно разделить на более мелкие, более управляемые куски.