自制大文件拆分器和粘合器(C语言描述)

最近想把台式机上的虚拟机用U盘拷贝到笔记本上,但是U盘太小,又不想花钱买大的,只好自己动手用 C 写一个 拆分器和粘合器,把大文件拆分成若干小文件,这样就可以用U盘分片段运输,最后把片段文件粘合一下就行了。


其实大文件的拆分和粘合是挺有用的,比如你可以在拆分时,分别对每个片段动一下手脚(每隔几个字节插入一个字节),这样就相当于文件加密了,因为,只有你知道是怎么拆分的,所以只有你知道怎么粘合最终文件。废话不多说,我们先来最简单的拆分(就是不动手脚的那种)。


我用的开发环境是 Visual Studio 2012 Express Desktop 中文版

拆分器源码:

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <windows.h>

void f拆分文件(FILE * o文件, int size);

int main()
{

_a1:
	printf("请输入分隔后每个片段的大小(单位:10mb)\n");

	int n片段大小 = 0;
	scanf("%d", &n片段大小);

	if(n片段大小 < 1 || n片段大小 > 50)
	{
		printf("片段大小超出预定范围,必须介于 1 和 50 之间\n");
		goto _a1;
	}

	printf("请输入要分隔的文件的完全路径(不要超过100个字符)\n");

_a2:
	char s目标文件路径[256];
	scanf("%s", s目标文件路径);

	FILE * o文件 = fopen(s目标文件路径, "rb");  /// BUG 记录:此处打开模式如果写成 “br”,则会在运行时抛出打开模式错误的异常
	if(o文件 == NULL)
	{
		printf("指定的文件打开时发生了错误,请重新指定文件\n");
		goto _a2;
	}
	f拆分文件(o文件, n片段大小);
	fclose(o文件);

	getchar();getchar();

}

void f全部写入(FILE * o文件, char * buffer, int count);

#define _1mb  (1024 * 1024)  //BUG 记录:如果这里的宏定义未加括号保护,则下面 printf 里的计算不正确

void f拆分文件(FILE * o文件, int size)
{
	int n拆分尺寸 = size * 10 * _1mb;

	int n待写入 = n拆分尺寸;
	int n欠写入 = 0;
	char * buffer = 0;   //BUG 记录:如果此处 写成 char buffer[_1mb]; 则在我机器上出现 函数栈溢出的运行时异常
	char * buffer2 = 0;

	int n片段序号 = 1;
	char s片段文件名[64];

	//建立 1mb 的缓存
	buffer = (char *)malloc(_1mb);
	if(buffer == NULL)
		return;

	//这里用 if(){...} 块会增加一个缩进和一个大括号嵌套,不利于代码阅读,还是用 goto 吧
_a3: 
	//创立片段文件
	sprintf(s片段文件名, "%d.cf", n片段序号);
	FILE * o片段 = fopen(s片段文件名, "wb");  /// BUG 记录:此处打开模式如果写成 “bw”,则会在运行时抛出打开模式错误的异常

	//处理欠写入的情况
	if(n欠写入 > 0)
	{
		f全部写入(o片段, buffer2, n欠写入);
		n待写入 -= n欠写入;
	}

	int n已读取 = 0;
	//写入片段文件
	while(n待写入 > 0)
	{
		n已读取 = fread(buffer, 1, _1mb, o文件);
		if(n已读取 < 1)
			break;

		if(n待写入 >= n已读取)
			n待写入 -= n已读取;
		else
		{
			n欠写入 = n已读取 - n待写入;
			n已读取 = n待写入;
			n待写入 = 0;
			buffer2 = buffer + n已读取;
		}

		//写入 n已读取 到片段文件
		f全部写入(o片段, buffer, n已读取);
	}
	fflush(o片段);
	fclose(o片段);
	n片段序号 += 1;
	printf("已写入片段文件:%s,大小:%f mb\n", s片段文件名, ((double)(n拆分尺寸 - n待写入)) / _1mb);  
	//BUG 记录:如果上面对 _1mb 的宏定义未加括号保护(#define _1mb (1024*1024)),则此处计算不正确

	n待写入 = n拆分尺寸;
	Sleep(1000);

	if(n已读取 > 0)
		goto _a3;

	free(buffer);
	printf("一共拆分成 %d 个子文件\n", n片段序号 - 1);
	return;
}


void f全部写入(FILE * o文件, char * buffer, int count)
{
	int n已写入 = 0;
	while(count > 0)
	{
		n已写入 = fwrite(buffer, 1, count, o文件);
		buffer += n已写入;
		count -= n已写入;
	}
}


拆分器运行截图



粘合器源码:

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <windows.h>

#define _1mb  (1024 * 1024)

void f全部写入(FILE * s读, FILE * s写, char * s缓存);

void main()
{
	char * s缓存 = (char *)malloc(_1mb);
	if(s缓存 == NULL)
	{
		printf("创建缓存失败\n");
		return;
	}

	FILE * s写入 = fopen("result.all", "wb");
	if(s写入 == NULL)
	{
		printf("创建写入文件失败\n");
		return;
	}

	int n片段序号 = 1;

_a1:
	char s读取文件名[64];
	sprintf(s读取文件名, "%d.cf", n片段序号);

	FILE * s读取 = fopen(s读取文件名, "rb");
	
	if(s读取 == NULL)
	{
		printf("片段文件 %s 不存在,停止操作\n", s读取文件名);
		goto _a2;
	}

	f全部写入(s读取, s写入, s缓存);
	fclose(s读取);
	printf("写入片段 %s \n", s读取文件名);
	Sleep(1000);
	n片段序号 += 1;
	goto _a1;


_a2:


	free(s缓存);
	fclose(s写入);

	printf("已经将所有片段文件粘合成 文件 result.all,请修改扩展名\n");
	getchar();getchar();
}


void f全部写入(FILE * o读, FILE * o写, char * s缓存)
{
	int n读入 = 0;
	while((n读入= fread(s缓存, 1, _1mb, o读)) > 0)
	{
		char * buffer = s缓存;
		while(n读入 > 0)
		{	
			int n已写 = fwrite(buffer, 1, n读入, o写);
			n读入 -= n已写;
			buffer += n已写;
		}
	}

	fflush(o写);
}

粘合器运行截图:



大家都看到了吧,先拆分成小文件,然后再将这些小文件粘合,最后的大文件就是原来那个(可用)。

欢迎到我的微博上去玩, weibo.com/litingsoft 


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值