【Linux系统】文件IO

Linux 文件与目录(文件IO)操作

Linux 文件与目录操作(文件 I/O)是Linux 系统编程中最基础、也是最重要的部分之一,几乎所有系统调用都会涉及文件描述符、文件操作或目录。

1. 一切皆文件(Everything is a file)

在 Linux 中,几乎所有系统资源都被看作"文件":

  • 普通文件(text、binary)
  • 目录
  • 设备文件(如 /dev/sda/dev/tty0
  • 套接字(socket)
  • 管道(pipe)

Linux 内核通过一个 文件描述符 (file descriptor, FD) 来引用打开的文件资源。

2. 文件描述符

  • 文件描述符是一个整数,从 0 开始编号。

  • 默认情况下,Linux 会自动为每个进程打开三个文件描述符,三个文件描述符分别对应如下:

    文件描述符 含义
    STDIN_FILENO (0) 标准输入(stdin)
    STDOUT_FILENO (1) 标准输出(stdout)
    STDERR_FILENO (2) 标准错误(stderr)

当你使用 open() 打开一个文件时,系统会返回一个新的文件描述符,如:3、4、5 等。

一、文件操作系统调用

文件操作的系统调用函数都在头文件 <fcntl.h>, <unistd.h>, <sys/stat.h> 中定义。

1. 打开文件 open()

c 复制代码
int open(const char *pathname, int flags, mode_t mode);
  • path:文件路径
  • flags:打开方式,如 O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_APPEND
  • mode:创建文件时的权限(如 0644

示例:

c 复制代码
#include <fcntl.h>
#include <stdio.h>

int fd = open("test.txt", O_RDWR | O_CREAT, 0644);
if (fd == -1) {
    perror("open");   // perror 在stdio.h中声明
}

2. 读写文件 read() / write()

c 复制代码
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
  • 返回值是实际读/写的字节数。
  • 返回 0 表示文件结束(EOF)。

示例(从文件读取一段内容):

c 复制代码
char buffer[128];
ssize_t n = read(fd, buffer, sizeof(buffer));
if (n > 0) {
    write(STDOUT_FILENO, buffer, n); // 输出到终端
}

3. 文件偏移与定位 lseek()

c 复制代码
off_t lseek(int fd, off_t offset, int whence);
  • offset:偏移量。

  • whence

    可取:

    • SEEK_SET:从文件开头偏移 offset
    • SEEK_CUR:从当前位置偏移
    • SEEK_END:从文件末尾偏移

示例(计算文件大小):

c 复制代码
off_t size = lseek(fd, 0, SEEK_END);
printf("File size: %ld bytes\n", size);

4. 关闭文件 close()

c 复制代码
int close(int fd);
  • 程序结束前要关闭打开的文件,释放资源。

5. 文件状态 stat()

c 复制代码
int stat(const char *path, struct stat *st);
  • 用于获取文件的元信息(权限、大小、时间、类型等)。

示例:

c 复制代码
struct stat st;
if (stat("test.txt", &st) == 0) {
    printf("Size: %ld, Mode: %o\n", st.st_size, st.st_mode);
}

示例程序:

c 复制代码
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>

int main() {
    char buff[10] = {0};
    printf("pid = %d\n", getpid());
    int fd = open("test.txt", O_RDWR | O_CREAT, 0644);
    if (fd == -1) {
        perror("open");  // perror在stdio.h头文件中声明
    }
    printf("fd = %d\n", fd);
    ssize_t read_len =  read(fd, buff, sizeof(buff));
    if (read_len == -1) {
        perror("read");
    }else if (read_len == 0) {
        perror("EOF");
    }
    /* 输出到终端 */
    ssize_t len =  write(STDOUT_FILENO, buff, sizeof(buff));
    printf("\noutput len = %ld\n",len);

    /* 偏移到文件结尾,计算文件大小 */
    off_t size = lseek(fd, 0, SEEK_END);
    printf("File size: %ld bytes\n", size);
    char str[] = "Hello World";
    /* 在文件结尾写入字符串 */
    write(fd, str, strlen(str));
    close(fd);

    struct stat st;   // stat 位于 <sys/stat.h> 中
    if (stat("test.txt", &st) == 0) {
        printf("Size: %ld, Mode: %o\n", st.st_size, st.st_mode);
    }
    return 0;
}

输出:

c 复制代码
1234567890
output len = 10
File size: 11 bytes
Size: 22, Mode: 100644
相关推荐
坤昱3 分钟前
cfs调度类深入解刨——psi科普篇
linux·cfs·psi·cfs调度·eevdf·psi详细分析·linux系统资源监控
骑上单车去旅行28 分钟前
openEuler 22.03 离线源码编译 Zabbix 7.0.27 完整最终整合手册
linux·运维·服务器·zabbix
向日葵.1 小时前
linux & qnx & git 命令 1
linux·运维·服务器
TDengine (老段)1 小时前
TDengine 物理计划生成 — 算子下沉、Exchange 与 Subplan 切分
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
2023自学中1 小时前
Linux 内核与用户空间 内存管理详解(堆与栈篇)
linux·嵌入式·内存·开发板
似水এ᭄往昔1 小时前
【Linux系统编程】--虚拟地址空间
linux·服务器
不会C语言的男孩1 小时前
Linux 系统编程 · 第 3 章:文件 I/O 基础
linux·服务器
yxl874646461 小时前
磐创PCTG-9013 Modbus转ProfibusDP工业协议转换器
网络·科技·物联网·gateway·信息与通信
MetrixAeroCore2 小时前
德国物联网卡出海适配解析|西欧合规组网通信方案(MetrixAeroCore)
物联网
金色光环2 小时前
DSP28335 SPI通信实验:从零到实战
单片机·嵌入式硬件·物联网