2016-04-27 2 views
1

Я делаю некоторые необычные манипуляции с данными. У меня 36 000 входных файлов. Более того можно сразу загрузить в память. Я хочу взять первый байт каждого файла и поместить его в один выходной файл, а затем сделать это снова для второго и так далее. Это не нужно делать в каком-либо конкретном порядке. Поскольку входные файлы сжаты, загрузка их занимает больше времени, и они не могут быть прочитаны 1 байт за раз. В итоге я получаю байтовый массив каждого входного файла.Прочитайте десятки тысяч файлов и напишите миллионы файлов в Java

Входные файлы около ~ 1-6 МБ несжатого и ~ .3-1MB сжимаются (сжатие с потерями). Выходные файлы в конечном итоге являются количеством входных файлов в байтах. ~ 36 КБ в моем примере.

Я знаю, что ulimit может быть установлен на ОС Linux, и эквивалент может быть выполнен на окнах. Несмотря на то, что этот номер может быть поднят, я не думаю, что любая ОС будет напоминать миллионы файлов, которые будут написаны одновременно.

Мое текущее решение состоит в том, чтобы сделать потоки буферизованного потока в 3000 или около того, загружая каждый входной файл по очереди и записывая от 1 байт до 3000 файлов, а затем закрывая файл и загружая следующий вход. С этой системой каждый входной файл должен быть открыт примерно по 500 раз.

Вся операция занимает 8 дней, и это всего лишь тестовый пример для более практичного приложения, которое будет содержать более крупные входные файлы, больше их и больше выходных файлов.

Улавливание всех сжатых файлов в памяти, а затем их распаковка по мере необходимости не является практичным и не будет масштабироваться до больших входных файлов.

Я думаю, что решение будет состоять в том, чтобы буферизировать, что я могу, из входных файлов (поскольку ограничения памяти не позволяют буферизировать все это), а затем последовательно записывать файлы, а затем делать все заново.

Однако я не знаю, есть ли лучшее решение, используя что-то, о чем я не читаю.

EDIT Я благодарен за быстрый ответ. Я знаю, что я расплывчатый в применении того, что я делаю, и я попытаюсь исправить это. У меня в основном есть трехмерный массив [изображения] [X] [Y] Я хочу перебирать каждое изображение и сохранять каждый цвет с определенного пикселя на каждом изображении и делать это для всех изображений. Проблемы связаны с ограничениями памяти.

byte [] pixels = ((DataBufferByte) ImageIO.read (fileList.get (k)) .getRaster(). GetDataBuffer()). GetData();

Это то, что я использую для загрузки изображений, потому что он выполняет декомпрессию и пропускает заголовок.

Я не редактирую его как видео, потому что мне нужно будет получить фрейм, а затем превратить его в изображение (дорогостоящее преобразование цветового пространства), а затем преобразовать его в байт [], чтобы получить пиксельные данные int RGB.

Я могу загрузить каждое изображение и разделить его на ~ 500 частей (размер Y) и записать в отдельные файлы. Я оставляю открытым и записываю для каждого изображения. Выходы будут легко доступны на концерте. Полученный файл может быть полностью загружен в память и превращен в массив для последовательной записи файлов.

Промежуточные шаги означают, что я мог бы разделить нагрузку на сеть, но я пытаюсь сделать это на ноутбуке низкого качества с 4 ГБ оперативной памяти, без графического процессора и с низким качеством i7.

Я не думал о том, чтобы сохранить что-либо в файл как промежуточный шаг, прежде чем читать ответ от Дэвидбака. Размер - единственное, что делает эту проблему не тривиальной, и теперь я вижу, что размер можно разделить на более мелкие более управляемые куски.

+0

не уверен, что часть 3 есть. Вам нужно распаковать файл и добавить первые несколько байтов в файл? почему до 3000 файлов? если у вас более 8 серверов, можно использовать hadoop – tgkprog

+0

. Входы имеют одинаковый размер для заданного прогона, но могут быть очень большого размера между прогонами, а также очень много файлов. Если бы это было 1 МБ на, и 36000 файлов, то это был бы 36-гигабайтный файл, и это был недостаток. Тогда я мог бы прочитать этот файл очень предсказуемым образом. Каждый байт, который мне нужен, был бы 1 МБ (размер одного входного файла) отдельно, но, учитывая количество времени, чтобы собрать его в один массивный файл, действительно ли это намного быстрее? Он будет загружать, а затем выгружать каждый байт из 36 концертов в память только для завершения 1 файла. Это сделало бы это 1 миллион раз. –

ответ

5

Трехфазные операции:

Фаза один: прочитать все входные файлы, по одному за раз, и записать в один выходной файл. Выходной файл будет ориентирован на запись - скажем, 8-байтовые записи, 4 байта «смещение символов» и 4-байтовый «код-символ». Когда вы читаете файл, смещение символов начинается с 0, конечно, поэтому, если входной файл «ABCD» вы пишете (0, A) (1, B) (2, C) (3, D) , Каждый входной файл открывается один раз, считывается последовательно и закрывается. Выходной файл открывается один раз, записывается последовательно, затем закрывается.

Этап второй. Используйте внешнюю сортировку для сортировки 8-байтных записей промежуточного файла в поле смещения символа 4 байта.

Этап 3. Откройте отсортированный промежуточный файл и пройдите через него. Открывайте новый выходной файл каждый раз, когда поле индекса символа изменяется и записывает в этот выходной файл все символы, принадлежащие этому индексу. Входной файл открывается один раз и читается последовательно. Каждый выходной файл открывается, записывается последовательно, затем закрывается.

Voilà! Вам нужно пространство для промежуточного файла и хороший внешний вид (и пространство для его рабочих файлов).

Как @Jorge предлагает, как фаза 1, так и фаза 2 могут быть распараллелены, и на самом деле такая работа, как указано (этапы с 1 по 3), находится точно в сладком месте mapreduce/hadoop.

2

Вы здесь очень расплывчаты, но, может быть, взгляд на mapreduce может помочь. Кажется, что такая работа может быть распределена.

С дополнительной информацией, которую вы предоставили, я действительно не вижу, как выполнить эту задачу на общем оборудовании, таком как 4 ГБ i7, о котором вы упомянули. Ваша проблема выглядит как алгоритм укладки изображений, чтобы получить достойное изображение из множества не очень хороших изображений, типичной проблемы в обработке астрономических изображений, и я уверен, что он применяется к другим областям. Хороший поиск в обработке астрономических изображений может быть хорошим использованием вашего времени, есть программное обеспечение под названием registax (не уверен, что оно все еще существует), что делает что-то подобное, но с видеофайлами.

Выполнение какой-либо математики салфетки, если вы возьмете 1 секунду, чтобы открыть файл, который вы получите 10h стоит только открыть файл.

Подход должен состоять в том, чтобы получить некоторый диск FAST (SSD), я бы распаковал все файлы в какой-то необработанный формат и сохранил их на диске, оттуда вам нужно будет использовать указатели файлов для чтения непосредственно из файлы, не загружая их в память и записывая вывод в файл прямо на диск.

+0

Спасибо указателю на RegiStax (который [все еще существует] (http://www.astronomie.be/registax/)). Я совершенно не знал о той категории программного обеспечения для обработки изображений. – davidbak

+0

Рад, что это помогло! –