【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
相关推荐
wj3055853787 小时前
课程 9:模型测试记录与 Prompt 策略
linux·人工智能·python·comfyui
abigriver7 小时前
打造 Linux 离线大模型级语音输入法:Whisper.cpp + 3090 显卡加速与 Rime 中英混输终极调优指南
linux·运维·whisper
wangqiaowq8 小时前
windows下nginx的安装
linux·服务器·前端
YYRAN_ZZU8 小时前
Petalinux新建自动脚本启动
linux
charlie1145141919 小时前
嵌入式Linux驱动开发pinctrl篇(1)——从寄存器到子系统:驱动演进之路
linux·运维·驱动开发
于小猿Sup9 小时前
VMware在Ubuntu22.04驱动Livox Mid360s
linux·c++·嵌入式硬件·自动驾驶
cen__y9 小时前
Linux12(Git01)
linux·运维·服务器·c语言·开发语言·git
不仙52011 小时前
VMware Workstation 26.0.0 在 Ubuntu 24.04 (内核 6.17.0) 上的安装与内核模块编译问题
linux·ubuntu·elasticsearch
AI视觉网奇11 小时前
linux 检索库 判断库是否支持
java·linux·服务器
dapeng-大鹏11 小时前
KVM+LVM 零停机在线扩容 Ubuntu 根分区:从磁盘添加到逻辑卷扩展完整
linux·运维·ubuntu·磁盘空间扩展