2012-06-24 5 views
3

У меня большой файл содержит около 250 миллионов символов. Теперь я хочу разбить его на части каждого, содержит 30 миллионов символов (так что первые 8 частей будут содержать 30 миллионов, а последняя часть будет содержать 10 миллионов символов). Еще один момент заключается в том, что я хочу включить в начале следующей части последние 1000 символов каждого файла (это означает, что последние 1000 символов первой части присоединяются к началу второй части, поэтому вторая часть содержит 30 миллионов 1000 символов и т. Д.). Может ли кто-нибудь помочь мне, как это сделать программно (используя Java) или с помощью команд Linux (быстро).Split File - Java/Linux

+1

Зачем вам перекрытие? Если вам это не нужно, вы можете просто использовать команды split и cat. –

+0

Мне очень любопытно узнать, что такое прецедент для перекрытия кусков. –

+0

@ RogerLindsjö, Нет. Мне нужно совпадение. – Arpssss

ответ

2

В одну сторону заключается в использовании регулярных команд unix для разделения файла и добавления последних 1000 байтов из предыдущего файла.

Первый разделить файл:

split -b 30000000 inputfile part. 

Затем для каждой части (игнорируя farst сделать новый файл, начиная с последних 1000 байт из предыдущего:

unset prev 
for i in part.* 
do if [ -n "${prev}" ] 
    then 
    tail -c 1000 ${prev} > part.temp 
    cat ${i} >> part.temp 
    mv part.temp ${i} 
    fi 
    prev=${i} 
done 

Перед сборкой мы снова итерации по файлам, игнорирование первого и выброс первых 1000 байт:

unset prev 
for i in part.* 
do if [ -n "${prev}" ] 
    then 
    tail -c +1001 ${i} > part.temp 
    mv part.temp ${i} 
    fi 
    prev=${i} 
done 

La й шаг, чтобы собрать файлы:

cat part.* >> newfile 

Поскольку не было никакого объяснения, почему перекрытие было необходимо, я просто создал его, а затем бросил ее.

2

Просто используйте с соответствующими параметрами команды split или csplit.

Возможно, вы захотите объединить эти программы с помощью более сложного сценария оболочки или с помощью какого-либо другого языка сценариев, чтобы дать им соответствующие аргументы (в частности, чтобы справиться с вашим перекрывающимся требованием). Возможно, вы можете комбинировать их с другими утилитами (например, grep или head или tail или sed или awk и т. Д.).

+0

У любого из них есть перекрывающиеся части, подобные OP? –

+0

Спасибо. Но нет ничего о шине по количеству символов и добавлении последних 1000 символов. – Arpssss

1

Вы можете сделать это, используя класс BreakIterator и его статический метод getCharacterInstance(). Он возвращает новый экземпляр BreakIterator для разрывов символов для локали по умолчанию.

Вы также можете использовать getWordInstance(), getLineInstance() .. сломать слова, строки ... и т.д.

например:

BreakIterator boundary = BreakIterator.getCharacterInstance(); 

boundary.setText("Your_Sentence"); 

int start = boundary.first(); 

int end = boundary.next(); 

For more detail look at this link:

http://docs.oracle.com/javase/6/docs/api/java/text/BreakIterator.html

2

Вы можете попробовать это. Я должен использовать read/mode в первый раз, поскольку файл не существовал вначале. Вы можете использовать только чтение, как это предлагает этот код.

long start = System.nanoTime(); 
long fileSize = 3200 * 1024 * 1024L; 
FileChannel raf = new RandomAccessFile("deleteme.txt", "r").getChannel(); 
long midPoint = fileSize/2/4096 * 4096; 
MappedByteBuffer buffer1 = raf.map(FileChannel.MapMode.READ_ONLY, 0, midPoint + 4096); 
MappedByteBuffer buffer2 = raf.map(FileChannel.MapMode.READ_ONLY, midPoint, fileSize - midPoint); 
long time = System.nanoTime() - start; 
System.out.printf("Took %.3f ms to map a file of %,d bytes long%n", time/1e6, raf.size()); 

Это работает на окне 7 x64 с 4 ГБ памяти.

Took 3.302 ms to map a file of 3,355,443,200 bytes long