我爱抄代码1-文件IO

一、复制文件

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);
}

 

posted @ 2022-04-19 11:22  Mars.wang  阅读(97)  评论(0编辑  收藏  举报