makefile
.PHONY:clean all CC=gcc CFLAGS=-Wall -g ###replace your bin BIN=simple_write simple_read copy_system all:$(BIN) %.o:%.c $(CC) $(CFLAGS) -c $< -o $@ clean: rm -f *.o $(BIN)
simple_write.c
/* #include <unistd.h> ssize_t write(int fd, const void *buf, size_t count); #include <string.h> size_t strlen(const char *s); */ /*unistd.h头文件必须放在前面, 它定义了posix有关的标志会影响到其他头文件 */ #include <unistd.h> #include <string.h> int main() { char *str="第一次测试write函数 "; int n=strlen(str); if(write(1,str,n) != n) write(2,"error ",6); return 0; }
simple_read.c
/* //man 3 exit #include <unistd.h> ssize_t read(int fd, void *buf, size_t count); #include <stdlib.h> void exit(int status); */ #include <stdlib.h> #include <unistd.h> int main() { char buf[1024]; int nread; nread=read(0, buf, 1024); if(nread == -1){ write(2,"error ",sizeof("error ")); exit(-1); } if(write(1,buf,nread) != nread){ write(2,"error ",sizeof("error ")); exit(-1); } return 0; } /*======================================+ + [shuai@shuaiPC 3rd]$ ./simple_read + hello world + hello world + [shuai@shuaiPC 3rd]$ ./simple_read + hello world + hello world + [shuai@shuaiPC 3rd]$ + + 注意 空格,制表,回车 + 管道命令 echo "hello" | ./simple_read + ========================================*/
copy_system.c
/* #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); int creat(const char *pathname, mode_t mode); #include <unistd.h> int close(int fd); #include <sys/ioctl.h> int ioctl(int d, int request, ...); */ #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main() { char c; int in, out; in = open("file.in", O_RDONLY);/*file.in自己准备*/ out=open("file.out", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); while(read(in, &c, 1)==1) write(out,&c, 1); return 0; }
主要几点需要记住
1. unistd.h头文件必须放在前面,它定义了posix有关的标志会影响到其他头文件。
2. 对文件,管道命令的理解
3. sizeof()和strlen() 对字符串求长度有点区别
4. read() write() 对空格 制表符 回车换行的处理
2016年11月23日22:54:51
==================================================================================================
[shuai@shuaiPC 11.23]$ TIMEFORMAT="" time ./copy_system 0.00user 0.02system 0:00.02elapsed 89%CPU (0avgtext+0avgdata 1360maxresident)k 0inputs+64outputs (0major+107minor)pagefaults 0swaps
用time工具对改程序进行尸检测算。1M的测试文件,使用以上代码在旧系统中会达到数百万次系统调用。--摘自书
进行改善的话,不使用逐个字符复制的办法,扩大缓冲块。
makefile
.PHONY:clean all CC=gcc CFLAGS=-Wall -g ###replace your bin BIN=copy_block copy_stdio all:$(BIN) %.o:%.c $(CC) $(CFLAGS) -c $< -o $@ clean: rm -f *.o $(BIN)
copy_block.c
/* #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); int creat(const char *pathname, mode_t mode); #include <unistd.h> int close(int fd); #include <sys/ioctl.h> int ioctl(int d, int request, ...); */ #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main() { char buf[1024]; int in, out, nread; in = open("file.in", O_RDONLY);/*file.in自己准备*/ out=open("file.out", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); while( (nread=read(in, buf, sizeof(buf))) >0 ) write(out,buf, nread); return 0; }
使用标准C写的copy程序
copy_stdio.c
/* #include <stdio.h> FILE *fopen(const char *path, const char *mode); #include <stdio.h> int fgetc(FILE *stream); #include <stdio.h> int fputc(int c, FILE *stream); */ #include <stdio.h> int main() { char c; FILE *in, *out; in = fopen("file.in","r"); out= fopen("file.out","w"); while((c=fgetc(in))!=EOF) { fputc(c,out); } return 0; }
主要几点需要记住
1. 复制程序的优化,适当调整缓冲区
2. scanf() gets()等函数的缺点,使用时考虑。
3. 还就是fopen_max的疑问
2016年11月24日23:14:03