Linux系统文件IO

1.IO文件分类

其实APP上面还有封装fopen/fread等函数,最大的特点就是引入了用户buff,使得去操作文件时,linux只用open一次文件,然后存入buff,这样提高了效率。具体需要进一步去了解。
Linux进阶-文件IO操作_io要求将当前路径下,所有文件的权限及最后一次的访问时间提取出来,-CSDN博客
 

2.IO编程

首先了解IO基本函数
 

2.1 文件描述符fd

在linux和其他unix操作系统中,文件描述符是一个非负整数,用来描述已经打开的文件。文件描述符是进程级别的概念,每个进程都有一个独立的文件描述符。

当进程启动时,通常会自动打开三个文件描述符

  • 0:标准输入(stdin)
  • 1:标准输出(stdout)
  • 2:标准错误输出(stderr)

2.2 open函数

我们可以在虚拟机系统上使用 man 2 open命令查看open函数的用法。需要的头文件和函数原型

#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);
pathname是文件路径,flags是指文件的打开模式一般有以下参数:

  • O_RDONLY:只读模式打开文件
  • O_WRONLY:只写模式打开文件
  • O_RDWR:读写模式打开文件
  • O_CREAT:如果文件不存在则创造文件
  • O_EXCL:与 O_CREAT 一起使用,如果文件已经存在则返回错误。
  • O_TRUNC:如果文件存在并且以写入模式打开,则将其长度截断为0
  • O_APPEND:追加模式打开文件

返回值:

成功:则返回fd也就是文件描述符(非负整数)
失败:返回-1,并设置“erron”以指示错误

实例:
 

int main(int argc,char **argv)
{
    int fd;

    if(argc != 2 )
    {
        printf("usage %s <file>\n",argv[0]);
        return -1;
    }
    /* 
    //int open(const char *pathname, int flags);
    int open(const char *pathname, int flags, mode_t mode);
    flags:O_RDONLY (只读),O_WRONLY (只写),O_RDWR (读写),O_CREAT,O_EXCL,O_TRUNC,O_APPEND
    mode_t mode:文件权限赋予
    */
    fd = open(argv[1],O_RDWR|O_CREAT|O_TRUNC,0777);

    if (fd < 0) {
        printf("can not open %s\n",argv[1]);
        perror("Failed to open file\n");
        printf("errno = %d\n",errno);
        printf("err %s\n",strerror(errno));
    } else {
        printf("fd = %d\n",fd);
    }

    while(1) {
        sleep(10);
    }
    close(fd);
    return 0;

}

我们使用open函数,去操作一个文件,如果这个文件存在而且以写模式打开则截取其长度为0,如果不存在,则创建这个文件并赋予对应的权限。能赋予的权限最终要看系统umask给的值。
例如umask 为0002,则表示,其他用户不能有写权限,那能拥有的权限则是取反后和赋予的权限相与。 

2.2 write函数

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);

fd:文件描述符(使用open函数打开文件时会返回文件描述符)
buf:写入的内容
count:写入的长度大小

实例:
 

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

/*
argc = 2
agrv[0] = "./open"
agrv[1] = "1.txt"
*/


int main(int argc,char **argv)
{
    int fd;
    int len;
    int i;
    if(argc < 3 )
    {
        printf("usage %s write <file> <string> <string> ...\n",argv[0]);
        return -1;
    }
    /* 
    //int open(const char *pathname, int flags);
    int open(const char *pathname, int flags, mode_t mode);
    flags:O_RDONLY (只读),O_WRONLY (只写),O_RDWR (读写),O_CREAT,O_EXCL,O_TRUNC,O_APPEND
    mode_t mode:文件权限赋予
    */
    fd = open(argv[1],O_RDWR|O_CREAT|O_TRUNC,0777);

    if (fd < 0) {
        printf("can not open %s\n",argv[1]);
        perror("Failed to open file\n");
        printf("errno = %d\n",errno);
        printf("err %s\n",strerror(errno));
    } else {
        printf("fd = %d\n",fd);
    }
    //ssize_t write(int fd, const void *buf, size_t count);
    for(i = 2;i < argc;i++) {
         len = write(fd,argv[i],strlen(argv[i]));
         if(len != strlen(argv[i])) {
            perror("Failed to write file\n");
            break;
         }
         write(fd,"\r\n",2);
    }

    //off_t lseek(int fd, off_t offset, int whence);
    //指定位置写入
    lseek(fd,3,SEEK_SET);
    write(fd,"666",3);

    close(fd);
    return 0;

}

2.3 read函数

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);
fd:文件描述符
buf:指向用于存储读取数据的缓冲区的指针,读出来的数据
count:请求读取的字节数

实例:
 

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

/*
argc = 2
agrv[0] = "./open"
agrv[1] = "1.txt"
*/


int main(int argc,char **argv)
{
    int fd;
    int len;
    unsigned char buf[100];
    if(argc !=2 )
    {
        printf("usage %s read <file>\n",argv[0]);
        return -1;
    }
    /* 
    //int open(const char *pathname, int flags);
    int open(const char *pathname, int flags, mode_t mode);
    flags:O_RDONLY (只读),O_WRONLY (只写),O_RDWR (读写),O_CREAT,O_EXCL,O_TRUNC,O_APPEND
    mode_t mode:文件权限赋予
    */
    fd = open(argv[1],O_RDONLY);

    if (fd < 0) {
        printf("can not open %s\n",argv[1]);
        perror("Failed to open file\n");
        printf("errno = %d\n",errno);
        printf("err %s\n",strerror(errno));
    } else {
        printf("fd = %d\n",fd);
    }

    //ssize_t read(int fd, void *buf, size_t count);
while(1) {

    len = read(fd,buf,sizeof(buf)-1);
    if (len < 0) {
        perror("read\n");
        close(fd);
        return -1;
    } else if (len == 0) {
        break;
    } else {
        buf[len] = '\0';
        printf("%s",buf);
    }
}

    close(fd);
    return 0;

}

2.4 close函数

close 函数用于关闭文件描述符,并释放与该文件描述符关联的资源
成功返回0,失败返回-1;

3.综合实验
 

我是跟着韦东山那边的老师一步一步学的。

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

/*
./005 data.csv result .csv
argc = 3
agrv[0] = "./005"
agrv[1] = "data.csv"
agrv[2] = "result .csv"
*/

#define max_len 1000


static int read_line(int fd,unsigned char *buf)
{
    /*循环读入一个字符*/
    /*如何判断读完一行?读到回车或者换行符 0x0d 0x0a*/
    unsigned char c;
    int len;
    int i = 0;
    int err = 0;
    while(1) {
        len = read(fd,&c,1);
        if (len <= 0) {
            err = -1;
            break;
        } else {
                buf[i] = c;
                i++;
            if(c == '\n') {
                /*碰到回车换行*/
                err = 0;
                break;
            }
        }
    }
    buf[i] = '\0';

    if (err && (i == 0)) {
        /*读到文件尾部,但没有数据*/
        return -1;
    } else {
        return i;

    }
}

int process_data(unsigned char *data_buf,unsigned char *result_buf)
{
    /*  示例1:  data_buf = ",语文,数学,英语,总分,评价"
                result_buf = ",语文,数学,英语,总分,评价"
        示例2: data_buf = "张三,90,91,92,,"
                result_buf = "张三,90,91,92,273,A+"
    */
   char name[100];
   int scores[3];
   int sum;
   char *levels[]={"A+","A","B"};
   int level;
   if(data_buf[0] == ',') {
    strcpy(result_buf,data_buf);
   } else {
        sscanf(data_buf,"%[^,],%d,%d,%d,",name,&scores[0],&scores[1],&scores[2]);
        //printf("result: %s,%d,%d,%d\n\r",name,scores[0],scores[1],scores[2]);
        //printf("result: %s --->get name--->%s\n\r",data_buf,name);
        sum = scores[0]+scores[1]+scores[2];
        if(sum >= 270) {
            level = 0 ;
        } else if(sum >= 240 && sum < 270) {
            level = 1;
        } else {
            level =2;
        }
            sprintf(result_buf,"%s,%d,%d,%d,%d,%s\n\r",name,scores[0],scores[1],scores[2],sum,levels[level]);
            //printf("result: %s",result_buf);

   }
}


int main(int argc,char **argv)
{
    int fd_data,fd_result;
    int len;
    int i;
    unsigned char data_buf[max_len];
    unsigned char result_buf[max_len];

    if(argc != 3 )
    {
        printf("usage %s <data csv file> <result csv file>  ...\n",argv[0]);
        return -1;
    }
    /* 
    //int open(const char *pathname, int flags);
    int open(const char *pathname, int flags, mode_t mode);
    flags:O_RDONLY (只读),O_WRONLY (只写),O_RDWR (读写),O_CREAT,O_EXCL,O_TRUNC,O_APPEND
    mode_t mode:文件权限赋予
    */
    fd_data = open(argv[1],O_RDONLY);
    fd_result = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0777);

    if (fd_data < 0) {
        printf("can not open file %s\n",argv[1]);
        perror("Failed to open file\n");
        return -1;
    } else {
        printf("fd_data = %d\n",fd_data);
    }

    fd_result = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0777);
    if (fd_result < 0) {
        printf("can not creat file %s\n",argv[1]);
        perror("Failed to result file\n");
        return -1;
    } else {
        printf("fd_result = %d\n",fd_result);
    }

    while(1) {
        /*读取一行*/
        len = read_line(fd_data,data_buf);
        if(len == -1) {
            break;
        }

#if 0
        if(len != 0) {
        printf("line: %s\n\r",data_buf);
        }
#endif
         /*处理数据*/
        //process_data(data_buf,result_buf);
        if(len != 0) {
        process_data(data_buf,result_buf);

        }


         /*写入结果文件*/
        //write_data(fd_result,result_buf);

        write(fd_result,result_buf,strlen(result_buf));

    }
    close(fd_data);
    close(fd_result);
    return 0;

}

 这边碰到几个坑,就是编码格式的问题,电脑默认csv文件是以ISO-8859格式保存,但是读取是用UTF-8格式,所以会在终端读取乱码,我在保存的时候用notepad++转码为UTF-8格式。

这个实验最终要的是了解IO的这些函数的用法吧,具体的一些处理文件的语法还是基本功问题。

4.文件系统IO内部调用机制

用户空间访问内核系统:

1.APP,调用系统接口(glbc)

2.触发异常,设置原因,调用汇编指令

3.进入liunx内核空间,分辨和处理异常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值