Разделенный файл, занимающий то же пространство памяти, что и исходный файл - PullRequest
0 голосов
/ 08 сентября 2011

У меня есть файл, скажем, размером 100 МБ.Мне нужно разделить его (например) на 4 разные части.Скажем, первый файл размером 0–20 МБ, второй - 20–60 МБ, третий - 60–70 МБ, последний - 70–100 МБ.Но я не хочу делать безопасное разбиение - на 4 выходных файла.Я хотел бы сделать это на месте.Таким образом, выходные файлы должны использовать то же место на жестком диске, которое занято этим одним исходным файлом, и буквально разделить его, не делая копию (поэтому в момент разделения мы должны потерять оригиналfile).

Другими словами, входной файл равен выходным файлам.

Возможно ли это, и если да, то как?

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

Язык программирования не имеет значения, мне просто интересно, возможно ли это.

Ответы [ 2 ]

3 голосов
/ 08 сентября 2011

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

Ни один из общих уровней абстракции файловой системы не поддерживает это; но помните, что они даже не поддерживают что-то столь же разумное, как «режим вставки» (который переписывает только один или два блока, когда вы вставляете что-то в середину файла вместо всех блоков), только режим перезаписи и добавления , Причины этого в значительной степени исторические, но текущая модель настолько укоренилась, что вряд ли более богатый API станет распространенным в ближайшее время.

1 голос
/ 08 мая 2012

Как я объясняю в этом вопросе о SuperUser, вы можете добиться этого, используя технику, изложенную Томом Зичем в его комментарии.

bigfile="mybigfile-100Mb"
chunkprefix="chunk_"
# Chunk offsets
OneMegabyte=1048576
chunkoffsets=(0 $((OneMegabyte*20)) $((OneMegabyte*60)) $((OneMegabyte*70)))

currentchunk=$((${#chunkoffsets[@]}-1))
while [ $currentchunk -ge 0 ]; do
    # Print current chunk number, so we know it is still running.
    echo -n "$currentchunk "
    offset=${chunkoffsets[$currentchunk]}
    # Copy end of $archive to new file
    tail -c +$((offset+1)) "$bigfile" > "$chunkprefix$currentchunk"
    # Chop end of $archive
    truncate -s $offset "$archive"
    currentchunk=$((currentchunk-1))
done

Вам нужно дать сценарию начальную позицию (смещение в байтах, ноль означает чанк, начиная с первого байта bigfile) каждого чанка, в порядке возрастания, как в пятой строке.

Если необходимо, автоматизируйте его, используя seq: Следующая команда выдаст chunkoffsets с одним чанком в 0, затем одним, начиная с 100k, а затем по одному на каждый мегабайт для диапазона 1-10 Мб (обратите внимание на -1 для last параметр, поэтому он исключается) затем один блок каждые два мегабайта для диапазона 10–20 МБ.

OneKilobyte=1024
OneMegabyte=$((1024*OneKilobyte))
chunkoffsets=(0 $((100*OneKilobyte)) $(seq $OneMegabyte $OneMegabyte $((10*OneMegabyte-1))) $(seq $((10*OneMegabyte-1)) $((2*OneMegabyte)) $((20*OneMegabyte-1))))

Чтобы увидеть, какие чанки вы установили:

for offset in "${chunkoffsets[@]}"; do echo "$offset"; done
0
102400
1048576
2097152
3145728
4194304
5242880
6291456
7340032
8388608
9437184
10485759
12582911
14680063
16777215
18874367
20971519

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

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

...