加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

TLPI-Chapter 4文件IO

发布时间:2020-12-15 16:16:03 所属栏目:安全 来源:网络整理
导读:所有执行I/O操作的系统调用都以文件描述符(一个非负整数)来指代打开的文件。文件描述符用以表示所有类型的已打开文件,包括管道、FIFO、socket、终端、设备、普通文件。它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一

所有执行I/O操作的系统调用都以文件描述符(一个非负整数)来指代打开的文件。文件描述符用以表示所有类型的已打开文件,包括管道、FIFO、socket、终端、设备、普通文件。它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。每个进程,文件描述符都自成一套。
三种标准的文件描述符:
0 标准输入 1 标准输出 2 标准错误
然后介绍执行文件IO操作的4个主要系统调用:
fd = open(pathname,flags,mode) 打开或创建一个新文件.

numread = read(fd,buffer,count) 读取fd所指代的文件中之多count字节的数据,并存储到buffer中.

numwritten = write(fd,count)调用从buffer中读取多达count字节的数据写入由fd指代的已打开的文件中.

status = close(fd)
释放文件描述符fd以及与之相关的内核资源.

改变文件偏移量:lseek()
off_t lseek(int fd,off_t offset,int whence)
offset参数指定了一个以字节为单位的数值
whence参数则表明赢参照哪个基点来解释offset参数,应为下列其中之一:
SEEK_SET:文件头部开始
SEEK_CUR:当前文件偏移量处
SEEK_END:文件结尾

.通用I/O模型以外的操作:ioctl()、fcntl()

ioctl()
ioctl()系统调用又为执行文件和设备操作提供了一种多用途机制。
int ioctl(int fd,int request,…);
request指定了将在fd上执行的控制操作
第三个参数…(argp)可以是任意数据类型,根据request的参数值来确定argp所期望的类型。通常情况,argp指向整数或结构的指针
fcntl()
fcntl()系统调用对一个打开的文件描述符执行一些列控制操作
int fcntl(intn fd,int cmd,…)
cmd参数所支持的操作范围很广
主要代码有两个:

#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-filen",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 */

    while ((numRead = read(inputFd,buf,BUF_SIZE)) > 0)
        if (write(outputFd,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);
}
#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':   /* Display bytes at current offset,as text */
        case 'R':   /* Display bytes at current offset,in hex */
            len = getLong(&argv[ap][1],GN_ANY_BASE,argv[ap]);

            buf = malloc(len);
            if (buf == NULL)
                errExit("malloc");

            numRead = read(fd,len);
            if (numRead == -1)
                errExit("read");

            if (numRead == 0) {
                printf("%s: end-of-filen",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':   /* Write string at current offset */
            numWritten = write(fd,&argv[ap][1],strlen(&argv[ap][1]));
            if (numWritten == -1)
                errExit("write");
            printf("%s: wrote %ld bytesn",argv[ap],(long) numWritten);
            break;

        case 's':   /* Change file offset */
            offset = getLong(&argv[ap][1],argv[ap]);
            if (lseek(fd,offset,SEEK_SET) == -1)
                errExit("lseek");
            printf("%s: seek succeededn",argv[ap]);
            break;

        default:
            cmdLineErr("Argument must start with [rRws]: %sn",argv[ap]);
        }
    }

    if (close(fd) == -1)
        errExit("close");

    exit(EXIT_SUCCESS);
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读