LINUX.ORG.RU
ФорумAdmin

Задача. Может есть хитрость?


0

0

Есть всего 2Гб дискового пространства. Есть архив (не важно какой - будь-то zip, tar или еще чего) размеров в 1.3Гб (в распакованном виде 1.6Гб). Собственно задача заключается в том, что бы распокавать архив на 2Гб дискового пространства.

Я это виду примерно так: архив распаковывается, распакованные файлы складываются в указанную директорию, а из архива удаляются. Есть такое?

★★★

Вот, написал маааленькую тулзу, которая делит большой файл на
несколько мелких, одновременно уменьшая размер делимого файла:

==========================compact_split.c==========================
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define BLOCK_SIZE 16384

void partCopy(const char *src, off_t src_pos, off_t size, const char *dst)
{
	int   fd_src, fd_dst;
	char  buf[BLOCK_SIZE];
	off_t s;
	
	fd_src = open(src, O_RDONLY);
	fd_dst = open(dst, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
	
	lseek(fd_src, src_pos, SEEK_SET);
	
	while (size)
	{
		if (size >= BLOCK_SIZE)
			s = BLOCK_SIZE;
		else
			s = size;
		
		read(fd_src, buf, s);;
		write(fd_dst, buf, s);
		
		size -= s;
	}
	
	close(fd_src);
	close(fd_dst);
}

int main(int argc, char *argv[])
{
	struct stat file_info;
	off_t       file_size, part_size, s;
	int         part_count, t;
	
	if (argc < 3)
	{
		printf("Usage:\n");
		printf("\tcompact_split <filename> <part size in bytes>\n");
		return 0;
	}
	
	stat(argv[1], &file_info);
	file_size = file_info.st_size;
	sscanf(argv[2], "%d", &t);
	part_size = t;
	printf("File \"%s\", size %d, part size %d.\n",
			argv[1], (int)file_size, (int)part_size);
			
	part_count = file_size/part_size;
	if (file_size%part_size)
		++part_count;
	printf("Splitting into %d parts...\n", part_count);
	t = part_count;
	while (file_size)
	{
		char new_file[256];
		
		if (file_size >= part_size)
			s = part_size;
		else
			s = file_size;
		
		snprintf(new_file, sizeof(new_file), "%s.%02d", argv[1], t);
		partCopy(argv[1], file_size - s, s, new_file);
		
		--t;
		file_size -= s;
		
		truncate(argv[1], file_size);
	
		printf("Created \"%s\", source truncated.\n", new_file);
	}
	unlink(argv[1]);
	
	printf("Finished!\n");

	return 0;
}
================================================================

Пример использования:

ivan@localhost ~/temp/spaceless_unpack $ gcc compact_split.c -o compact_split

ivan@localhost ~/temp/spaceless_unpack $ ./compact_split
Usage:
        compact_split <filename> <part size in bytes>

ivan@localhost ~/temp/spaceless_unpack $ ls -lh big-archive.tar
-rw-r--r-- 1 ivan ivan 1,3G Фев  9 23:22 big-archive.tar

ivan@localhost ~/temp/spaceless_unpack $ ./compact_split big-archive.tar 100000000
File "big-archive.tar", size 1337876480, part size 100000000.
Splitting into 14 parts...
Created "big-archive.tar.14", source truncated.
Created "big-archive.tar.13", source truncated.
Created "big-archive.tar.12", source truncated.
Created "big-archive.tar.11", source truncated.
Created "big-archive.tar.10", source truncated.
Created "big-archive.tar.09", source truncated.
Created "big-archive.tar.08", source truncated.
Created "big-archive.tar.07", source truncated.
Created "big-archive.tar.06", source truncated.
Created "big-archive.tar.05", source truncated.
Created "big-archive.tar.04", source truncated.
Created "big-archive.tar.03", source truncated.
Created "big-archive.tar.02", source truncated.
Created "big-archive.tar.01", source truncated.
Finished!

ivan@localhost ~/temp/spaceless_unpack $ for f in big-archive.tar.*; do cat "${f}"; rm -f "${f}"; done | tar -vx
srv/ftp/pub/software/games/etqw/datafiles/pak000.pk4
srv/ftp/pub/software/games/etqw/datafiles/pak001.pk4
srv/ftp/pub/software/games/etqw/datafiles/pak002.pk4
srv/ftp/pub/software/games/etqw/datafiles/pak003.pk4
srv/ftp/pub/software/games/etqw/datafiles/pak004.pk4
srv/ftp/pub/software/games/etqw/datafiles/zpak_russian000.pk4

Deleted
()
Ответ на: комментарий от Deleted

Забыл сказать:

1) Проверки ошибок нет никакой.
2) Работоспособность и отсутствие глюк не гарантируется =).
3) Не работает с файлами >2gb.

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.