关于Linux/Unix系统编程手册第四章的练习二的解答

我想分享一下我的解答,因为我觉得很多人的解答不对,他们仅仅是将空洞复制成了’\0’写入了磁盘而已。正确的方法应该是遇到’\0’就调用lseek。(假设不会有除空洞外的原因使’\0’在被读文件中存在)所以下面是我写的代码。
p.s.如果空洞很大的话,那么空洞就有存在的必要,所以只有小部分空洞真的被写入了’\0’,其他空洞只是在读出时表现为’\0’而已。(这只是我的理解)

#include <sys/stat.h>
#include <fcntl.h>
#include "tlpi_hdr.h"

int main (int argc, char **argv) {
	char buf[BUFSIZ];
	int src, dst, sflag, dflag, rnum, wnum;
	mode_t smode, dmode;
	off_t soffset, doffset;

	if (argc != 3)
		usageErr("Only 2 arguments are permitted");

	sflag = O_RDONLY;
	dflag = O_WRONLY | O_CREAT | O_TRUNC;
	smode = S_IRUSR | S_IRGRP | S_IROTH;
	dmode = S_IRUSR | S_IRGRP | S_IROTH |
		S_IWUSR | S_IWGRP | S_IROTH;
	if ((src = open(argv[1], sflag, smode)) == -1 ||
	    (dst = open(argv[2], dflag, dmode)) == -1)
		errExit("Can't open file in arguments");

	while ((rnum = read(src, buf, BUFSIZ)) > 0) {
		int i = 0, mark = 0;
		while(i < rnum) {
			if (buf[i] == '\0') {
				wnum = write(dst, &buf[mark], i-mark);
				if(wnum != i-mark)
					errExit("Can't write to %s", argv[2]);

				int step = 1;
				while (++i<rnum && buf[i] == '\0')
					step++;
				lseek(dst, step, SEEK_CUR);
				mark = i;
			}
			else
				i++;
		}

		if (mark != rnum) {
			wnum = write(dst, &buf[mark], rnum-mark);
			if(wnum != rnum-mark)
				errExit("Can't write to %s", argv[2]);
		}
	}

	if(rnum == -1)
		errExit("Can't read %s", argv[1]);
	exit(EXIT_SUCCESS);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值