一、复制文件
copy.c来自《linux-Unix系统编程手册》,用来将一个源文件,复制到一个目标文件
执行命令:copy oldFile newFile
copy.c
#include <sys/stat.h> #include <fcntl.h> #include "tlpi_hdr.h" #ifndef BUF_SIZE /* Allow "cc -D" to override definition */ #define BUF_SIZE 1024 #endif int main(int argc, char *argv[]) { //输入文件描述符、输出文件描述符、打开配置 int inputFd, outputFd, openFlags; mode_t filePerms; ssize_t numRead; char buf[BUF_SIZE]; if (argc != 3 || strcmp(argv[1], "--help") == 0) usageErr("%s old-file new-file\n", argv[0]); /* Open input and output files */ //以只读方式打开文件 inputFd = open(argv[1], O_RDONLY); if (inputFd == -1) errExit("opening file %s", argv[1]); openFlags = O_CREAT | O_WRONLY | O_TRUNC; filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; /* rw-rw-rw- */ //打开目标文件,不存在则创建 outputFd = open(argv[2], openFlags, filePerms); if (outputFd == -1) errExit("opening file %s", argv[2]); /* Transfer data until we encounter end of input or an error */ //通过一个1024字节的缓存把输入复制到输出 while ((numRead = read(inputFd, buf, BUF_SIZE)) > 0) if (write(outputFd, buf, numRead) != numRead) fatal("couldn't write whole buffer"); if (numRead == -1) errExit("read"); if (close(inputFd) == -1) errExit("close input"); if (close(outputFd) == -1) errExit("close output"); exit(EXIT_SUCCESS); }
二、重定位文件偏移量
对于每个打开的文件,系统内核会记录其文件偏移量,有时也将文件偏移量称为读写偏移量或指针。文件偏移量是指执行下一个 read()或 write()操作的文件起始位置,会以相对于文件头部起始点的文件当前位置来表示。文件第一个字节的偏移量为 0。
执行案例:
seek_io file s0 w54321
输出:
s0: seek succeeded
w54321: wrote 5 bytes
执行:
seek_io file s0 r5
输出:
s0: seek succeeded
r5: 54321
seek_io.c
#include <sys/stat.h> #include <fcntl.h> #include <ctype.h> #include "tlpi_hdr.h" int main(int argc, char *argv[]) { size_t len; off_t offset; int fd, ap, j; char *buf; ssize_t numRead, numWritten; if (argc < 3 || strcmp(argv[1], "--help") == 0) usageErr("%s file {r<length>|R<length>|w<string>|s<offset>}...\n", argv[0]); //打开文件 fd = open(argv[1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); /* rw-rw-rw- */ if (fd == -1) errExit("open"); //第一轮循环重定位偏移量,第二轮进行读写 for (ap = 2; ap < argc; ap++) { switch (argv[ap][0]) { case 'r': /* 打印当前偏移量的字符串 */ case 'R': /* Display bytes at current offset, in hex */ //getLong把命令行的第二个参数的s5转成数字5 len = getLong(&argv[ap][1], GN_ANY_BASE, argv[ap]); //为缓冲区分配内存 buf = malloc(len); if (buf == NULL) errExit("malloc"); numRead = read(fd, buf, len); if (numRead == -1) errExit("read"); if (numRead == 0) { printf("%s: end-of-file\n", argv[ap]); } else { printf("%s: ", argv[ap]); for (j = 0; j < numRead; j++) { if (argv[ap][0] == 'r') printf("%c", isprint((unsigned char) buf[j]) ? buf[j] : '?'); else printf("%02x ", (unsigned int) buf[j]); } printf("\n"); } //释放缓存区 free(buf); break; case 'w': /* 在当前文件偏移量写入字符串 */ numWritten = write(fd, &argv[ap][1], strlen(&argv[ap][1])); if (numWritten == -1) errExit("write"); printf("%s: wrote %ld bytes\n", argv[ap], (long) numWritten); break; case 's': /* 改变偏移量 */ offset = getLong(&argv[ap][1], GN_ANY_BASE, argv[ap]); //移动文件游标偏移量,偏移量的起始位置可选: //SEEK_SET=文件起始点,SEEK_CUR=当前偏移量,SEEK_END=文件尾部 if (lseek(fd, offset, SEEK_SET) == -1) errExit("lseek"); printf("%s: seek succeeded\n", argv[ap]); break; default: cmdLineErr("Argument must start with [rRws]: %s\n", argv[ap]); } } //关闭文件 if (close(fd) == -1) errExit("close"); exit(EXIT_SUCCESS); }