Linux - 文件操作

1. 简述

记--Linux环境下C语言编程的文件操作。

两种操作文件的方式:

1、系统I/O:系统调用接口,open(), read(), write(), lseek(), close()。是操作系统直接提供的编程接口(API)。 系统I/O常用于硬件级别,可以设置读缓冲区,一般没有写缓冲区;

2、标准/IO:标准库的I/O函数,fopen(), fread(), fwrite(), fseek(), fclose(),是对系统调用接口进一步封装。 标准I/O常用于软件级别,自带读写缓冲区。

 

2. 系统I/O

2.1 open()函数

补充说明:

1)flags 的各种取值可以用位或的方式叠加起来,例如创建文件的时候需要满足这样的 选项:读写方式打开,不存在要新建,如果存在了则清空。则flags 的取值应该是:O_RDWR | O_CREAT | O_TRUNC。

2)mode 是八进制权限,比如0644,或者0755 等。也可以是使用系统已定义的

S_IRWXU 00700 user (file owner) has read, write, and execute permission //用户可读写执行权限

S_IRUSR 00400 user has read permission//用户写权限

S_IWUSR 00200 user has write permission//用户写权限

S_IXUSR 00100 user has execute permission//用户执行权限 (更多选项可查询man手册:man 2 open)

比如新创建的文件权限只需要读写权限:S_IRUSR | S_IWUSR

3)文件描述符

其实是一个数组的下标值,在内核中打开的文件是用 file 结构体来表示的,每一个结构体都会有一个 指针来指向它们,这些指针被统一存放在一个叫做 fd_array 的数组当中,而这个数组被存 放在一个叫做 files_struct 的结构体中,该结构体是进程控制块 task_struct 的重要组成部分。

2.2 close()函数

2.3 read()函数

补充说明:

ssize_t :是类型重定义,为了跨平台兼容。比如说long在32位系统可能是4字节,64位系统可能是8字节,嵌入式开发有的只有16位,那么int只有2个字节。

但是在编程时往往需要根据类型大小来进行操作数据,例如在64位系统编程时8字节使用long类型,如果移植到32位系统时long只有4字节,那么就需要改动好多个地方,所以重定义一种类型,然后根据实际系统再指定,方便改动移植。例如:重定义ssize类型是8字节的,在32位系统,我可以将long long重定义为ssize类型,如果是64位系统可以定义为long类型,这样只需改动一处。

2.4 write()函数

2.5 lseek()函数

 

示例代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
​
int main(int argc,char* argv[])
{
  int fd;
  int wr_ret;
  int rd_ret;
  unsigned long file_size;
  char wr_buf[100] = "hello world";
  char rd_buf[100];
​
  fd = open("a.txt", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IROTH);//等价于fd = open("a.txt", O_RDWR | O_CREAT | O_TRUNC, 0x604);
  if(fd == -1)
  {
    perror("open file error:");//只有上面的函数设置了error全局错误号,才可使用,会根据error输出对应的错误信息
    return -1;
  }
  printf("fd = %d\n", fd);
​
  wr_ret = write(fd, wr_buf, sizeof(wr_buf));
  if(wr_ret == -1)
  {
    perror("write file error:");
    return -1;
  }
  printf("wr_ret = %d\n", wr_ret);
​
  lseek(fd, 0, SEEK_SET);//上面的写操作,文件位置偏移量也会相应的移动,此处将文件偏移到文件开始位置,然后才能读取刚刚输入的内容
  rd_ret = read(fd, rd_buf, sizeof(rd_buf));
  if(rd_ret == -1)
  {
    perror("read file error:");
    return -1;
  }
  printf("rd_ret = %d\n",rd_ret);
  printf("content=%s\n", rd_buf);
​
  file_size = lseek(fd, 0, SEEK_END);
  printf("file_size = %lu\n", file_size);
​
  close(fd);//关闭文件
​
  return 0;
}

运行结果:

 

2.6 mmap()函数

更多请查看man手册:man 2 mmap

 

示例代码:

#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h> //mencpy()

int main(void)
{
  int fd;
  char *map_ptr;
  int retval;
    
  fd = open("a.txt",O_RDWR);
   if(fd == -1)
  {
    perror("打开文件失败!");
    return -1;
  }
    
  map_ptr = mmap( NULL, 100, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
  if(map_ptr == MAP_FAILED)
  {
    perror("映射内存失败!");
    return -1;
  }
  printf("%s", map_ptr);

  memcpy(map_ptr, "haha", 5);

  retval = munmap(map_ptr, 100);
  if(retval == -1)
  {
    perror("munmap 失败!");
    return -1;
  }

  close(fd);

  return 0;
}

运行结果:

 

3. 标准I/O

3.1 fopen()函数

程序一开始默认打开3个文件

3.2 fclose()函数

3.3 fread()函数

3.4 fwrite()函数

3.5 fseek()函数

3.6 ftell()函数

3.7 rewind()函数

 

简单例子:

#include <stdio.h>
​
int main(int argc,char* argv[])
{
  int wr_ret;
  int rd_ret;
  FILE *fp;
  unsigned long file_size;
  char wr_buf[100] = "hello world";
  char rd_buf[100];
​
  fp = fopen( "a.txt", "a+" );//文件追加,可读可写,文件不存在则创建
  if(fp == NULL)
  {
    perror("open file error:");//只有上面的函数设置了error全局错误号,才可使用,会根据error输出对应的错误信息
    return -1;
  }
​
  wr_ret = fwrite( wr_buf, sizeof(wr_buf), 1, fp);
  printf("wr_ret = %d\n", wr_ret);
​
  rewind(fp);//上面的写操作,文件位置偏移量也会相应的移动,此处将文件偏移到文件开始位置,然后才能读取刚刚输入的内容
  rd_ret = fread(rd_buf, sizeof(rd_buf), 1, fp);
  printf("rd_ret = %d\n",rd_ret);
  printf("content=%s\n", rd_buf);
​
  fseek(fp, 0, SEEK_END);
  file_size = ftell(fp);
  printf("file_size = %lu\n", file_size);
​
  fclose(fp);//关闭文件
​
  return 0;
}

运行结果

 

 

————————————————

版权声明:本文为CSDN博主「Genven_Liang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/nanfeibuyi/article/details/81456273

posted @ 2023-01-06 11:46  [BORUTO]  阅读(94)  评论(0编辑  收藏  举报