1.linux系统编程之文件

linux系统编程之文件

linux的文件编程可以用来操作linux里面的系统,如打开文件、保存文件的操作我们通过代码来实现。

1.linux系统提供了的API

  • 打开文件:open
  • 读写文件:read/write
  • 光标定位:lseek
  • 关闭:close

可以通过man命令查看对应的api详情,如:

man open

2.打开文件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);
  • pathname:文件的名称
  • flags:打开文件的权限,必须参数有O_RDONLY, O_WRONLY, or O_RDWR,可选参数:O_CLOEXEC,O_CREAT, O_DIRECTORY, O_EXCL, O_NOCTTY, O_NOFOLLOW, O_TMPFILE, and O_TRUNC
    • O_RDONLY:只读权限
    • O_WRONLY:只写权限
    • O_RDWR:可读可写权限
  • 返回值:打开失败返回-1

实例:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int main()
{
	int fd;
	fd = open("./file1",O_RDWR);
	printf("fd=%d\n",fd);
        return 0;
}

3.读写文件read/write

read函数原型:

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);
  • fd:open打开文件时,返回的fd
  • void *buf:可读一个int类型、char类型,结构体类型的指针
  • size_t count:所需要读取的大小
  • 返回值:读取失败返回-1,返回读取的实际大小

write函数原型:

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);
  • fd:open打开文件时,返回的fd
  • const void *buf:可写一个int类型、char类型,结构体类型的指针
  • size_t count:所需要写入的大小
  • 返回值:写入失败返回-1,返回写入的count大小

4.光标定位lseek

函数原型:

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

off_t lseek(int fd, off_t offset, int whence);
  • fd:open打开文件时,返回的fd
  • offset:偏移量,对当前光标偏移多少,相对whence而言,一般填写0
  • whence:设置光标的位置,SEEK_SET、SEEK_CUR、SEEK_END
    • SEEK_SET:重置光标的位置到头部
    • SEEK_CUR:获取到当前光标的位置
    • SEEK_END:设置光标的位置到末尾
  • 返回值:失败返回-1,成功返回当前光标的位置

5.关闭close

函数原型:用来关闭打开的文件,释放文件资源

#include <unistd.h>

int close(int fd);
  • fd:open打开文件时,返回的fd
  • 返回值:返回0关闭成功,返回-1关闭失败

6.c标准库对文件的操作

在Linux环境下使用C标准库进行文件操作是系统编程的基础。C标准库提供了一组函数用于文件的创建、读写、定位和关闭等操作。以下是主要的文件操作函数及其用法:

1. 文件打开与关闭

fopen()

FILE *fopen(const char *pathname, const char *mode);
  • 功能:打开文件
  • 参数:
    • pathname:文件路径
    • mode:打开模式
      • "r":只读
      • "w":只写(文件存在则清空,不存在则创建)
      • "a":追加(文件末尾写入)
      • "r+":读写(文件必须存在)
      • "w+":读写(文件存在则清空,不存在则创建)
      • "a+":读写(从文件末尾开始)
  • 返回值:成功返回FILE指针,失败返回NULL

fclose()

int fclose(FILE *stream);
  • 功能:关闭文件
  • 参数:stream:要关闭的文件指针
  • 返回值:成功返回0,失败返回EOF

2. 文件读写操作

字符读写

int fgetc(FILE *stream);
int fputc(int c, FILE *stream);
  • fgetc():从文件读取一个字符
  • fputc():向文件写入一个字符

行读写

char *fgets(char *s, int size, FILE *stream);
int fputs(const char *s, FILE *stream);
  • fgets():从文件读取一行(包括换行符)
  • fputs():向文件写入字符串(不自动添加换行符)

二进制读写

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
  • fread():从文件读取二进制数据
  • fwrite():向文件写入二进制数据

3. 文件定位

int fseek(FILE *stream, long offset, int whence);
long ftell(FILE *stream);
void rewind(FILE *stream);
  • fseek():设置文件位置指针
    • whence:SEEK_SET(文件开头)、SEEK_CUR(当前位置)、SEEK_END(文件末尾)
  • ftell():获取当前文件位置
  • rewind():将文件位置指针重置到文件开头

4. 错误处理

int ferror(FILE *stream);
int feof(FILE *stream);
void clearerr(FILE *stream);
  • ferror():检查文件错误
  • feof():检查是否到达文件末尾
  • clearerr():清除错误标志

5. 示例代码

示例1:文件复制

#include <stdio.h>

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <source> <destination>\n", argv[0]);
        return 1;
    }

    FILE *src = fopen(argv[1], "rb");
    if (!src) {
        perror("Failed to open source file");
        return 1;
    }

    FILE *dst = fopen(argv[2], "wb");
    if (!dst) {
        perror("Failed to open destination file");
        fclose(src);
        return 1;
    }

    char buffer[4096];
    size_t bytes;
    while ((bytes = fread(buffer, 1, sizeof(buffer), src)) > 0) {
        fwrite(buffer, 1, bytes, dst);
    }

    fclose(src);
    fclose(dst);
    return 0;
}

示例2:逐行读取文件

#include <stdio.h>

int main() {
    FILE *fp = fopen("example.txt", "r");
    if (!fp) {
        perror("Failed to open file");
        return 1;
    }

    char line[256];
    while (fgets(line, sizeof(line), fp)) {
        printf("%s", line);
    }

    if (ferror(fp)) {
        perror("Error reading file");
    }

    fclose(fp);
    return 0;
}

6. 注意事项

  1. 总是检查文件操作函数的返回值
  2. 确保在不再需要文件时关闭它们
  3. 区分文本模式和二进制模式(在Windows上特别重要)
  4. 注意缓冲区的使用,特别是对于大文件操作
  5. 考虑使用setvbuf()调整缓冲区大小以提高性能

C标准库的文件操作是跨平台的,在Linux环境下通常是对系统调用(如open、read、write等)的封装,提供了更高级别的抽象和缓冲机制。

posted @ 2025-06-27 20:07  站着说话不腰疼  阅读(24)  评论(0)    收藏  举报