【Linux】系统文件IO

系统调用接口

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);
  • 参数:
  1. pathname: 要打开或创建的目标文件
  2. flags: 打开文件时,可以传入多个参数选项,用下面的一个或者多个常量进行“或”运算,构成flags。 可选参数:
    O_RDONLY: 只读打开  O_WRONLY: 只写打开  O_RDWR : 读,写打开
    上面这三个常量,必须指定一个且只能指定一个
    O_CREAT : 若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限
    O_APPEND: 追加写
    O_TRUNC:打开同时截断文件为0长度
  3. mode:文件创建权限(最后文件的权限是mode &~ umask)
    可以通过mode_t umask(mode_t mask);函数将当前进程的文件创建权限掩码修改为mask
  • 返回值:
    成功:新打开的文件描述符
    失败:-1
write
#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);
  • 参数:
    fd: open打开文件所返回的文件描述符
    buf:要写入的数据
    count:要写入的字节数
  • 返回值:实际写入的字节数 失败:-1
read
#include <unistd.h>

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

从fd文件中读取count长度的数据放到buf中
返回值:返回实际读取到的字节数, 失败: -1

lseek
#include <sys/types.h>
#include <unistd.h>

off_t lseek(int fd, off_t offset, int whence);

跳转到fd文件的读写位置到指定处
whence : SEEK_SET(文件头)  SEEK_CUR(当前)   SEEK_END(文件尾)
offset: 偏移量(负值表示whence向前位置)

close
#include <unistd.h>

int close(int fd);

关闭一个文件描述符 , 使它不再指向任何文件和可以在新的文件操作中被再次使用.任何与此文件相关联的以及程序所拥有的锁, 都会被删除(忽略那些持有锁的文件描述符)

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

int main() {
  //将当前进程的文件创建权限掩码修改成为mask
  umask(0);

  int fd = open("./test.txt", O_RDWR | O_CREAT | O_APPEND | O_TRUNC, 0777);
  if (fd < 0) {
    perror("open error");
    return -1;
  }

  char* buf = "hello ya\n";
  ssize_t ret = write(fd, buf, strlen(buf));
  if (ret < 0) {
    perror("write error");
    return -1;
  }

  lseek(fd, 0, SEEK_SET);

  char buff[1024] = { 0 };
  ret = read(fd, buff, 1023);
  if (ret < 0) {
    perror("read error");
    return -1;
  }
  printf("ret:%d-[%s]]\n", ret, buff);

  close(fd);
  return 0;
}

文件描述符fd

文件描述符就是从0开始的小整数。当我们打开文件时,操作系统在内存中要创建相应的数据结构来描述目标文件。于是就有了file结构体。表示一个已经打开的文件对象。而进程执行open系统调用,所以必须让进程和文件关联起来每个进程都有一个指针*files, 指向一张表files_struct,该表最重要的部分就是包涵一个指针数组,每个元素都是一个指向打开文件的指针!所以,本质上,文件描述符就是该数组的下标。所以,只要拿着文件描述符,就可以找到对应的文件

  • Linux进程默认情况下会有3个缺省打开的文件描述符,分别是标准输入0, 标准输出1, 标准错误2
    在这里插入图片描述
文件描述符的分配规则:最小未使用

体会最小未使用:下述代码首先关闭了默认打开的标准输出文件,然后打开“./test.txt”文件,这时printf的内容并没有打印到显示器,而是写到了“test.txt”文件中。

int main() {
	close(1);
    int fd = open("./test.txt", O_CREAT | O_RDWR, 0664);
    if (fd < 0) {
    	perror("open error");
    	return -1;
 	}
 	printf("fd:%d\n", fd);
    close(fd);
    return 0;
}     

注:printf函数使用的是write接口,操作的是fd为1的文件。因为1被关闭,这时最小未使用的文件描述符为1,所以打开“test.txt”文件时被分配为1。printf打印的内容就被打印到文件描述符为1的文件即“test.txt”文件。

在这里插入图片描述

重定向

重定向指的是文件描述符的重定向;文件描述符这个下标中的文件描述信息,从-一个文件变成了另- -个文件;
这时候当用户通过文件描述符向文件写入数据的时候,文件描述符并没有变,依然还是相同的数字;但是因为描述符下标中的文件描述信息的改变,而导致数据流向另-个文件(像上面的printf)

#include <unistd.h>

int dup(int oldfd);
int dup2(int oldfd, int newfd);

将oldfd描述符对应的描述信息,向newfd中拷贝一份
让newfd也指向oldfd所指向的文件
若newfd本身已经有打开的文件,则关闭关闭这个文件

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值