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