Linux学习笔记:文件IO

之前学了标准IO,这篇整理文件IO的部分。文件IO是Linux内核提供的接口,属于系统调用,操作对象是文件描述符而不是FILE指针。核心就四个:open打开、read读、write写、close关闭。

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。

flags是打开方式,常用的:

  • O_RDONLY:只读

  • O_WRONLY:只写

  • O_RDWR:读写

  • O_CREAT:创建

  • O_TRUNC:清空

  • O_APPEND:追加

可以组合使用,比如标准IO的"w"对应 O_WRONLY | O_TRUNC | O_CREAT ,mode给0664。"a"对应 O_WRONLY | O_CREAT | O_APPEND 。

mode参数是文件权限,实际权限是 mode & ~umask ,普通文件一般给0664。

文件描述符:打开文件时系统分配的一个小的非负整数,用来标记这个文件。默认范围0-1023,共1024个,分配原则是最小未被使用。系统默认已经打开三个:

  • 0 ------ STDIN_FILENO,标准输入

  • 1 ------ STDOUT_FILENO,标准输出

  • 2 ------ STDERR_FILENO,标准出错

close

#include <unistd.h>

int close(int fd);

关闭文件,成功返回0,失败返回-1。打开的文件用完一定要关,不然会造成文件描述符泄露。

write

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

向文件写入count字节的数据,成功返回实际写入的字节数,失败返回-1。

read

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

从文件读取数据,成功返回实际读到的字节数,到达文件末尾返回0,失败返回-1。

用read和write实现文件拷贝:

int file_copy(const char *srcfile, const char *dstfile)

{

int fdsrc = open(srcfile, O_RDONLY);

int fddst = open(dstfile, O_WRONLY | O_CREAT | O_TRUNC, 0664);

if (-1 == fdsrc || -1 == fddst)

{

printf("open error\n");

return -1;

}

char buff1024 = {0};

ssize_t size = 0;

while ((size = read(fdsrc, buff, sizeof(buff))) > 0)

{

write(fddst, buff, size);

}

close(fdsrc);

close(fddst);

return 0;

}

lseek

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

重新定位文件的读写位置。whence有三个取值:

  • SEEK_SET:从文件开头偏移

  • SEEK_CUR:从当前位置偏移

  • SEEK_END:从文件末尾偏移

成功返回当前位置到文件开头的偏移量,失败返回-1。可以用来求文件大小,也可以创建空洞文件抢占磁盘空间。

文件IO和标准IO的区别

标准IO 文件IO

操作对象 FILE *(文件流指针) fd(文件描述符)

性质 标准C库函数,可移植性强 Linux系统调用,可移植性弱

缓冲区 有缓冲区,减少用户层和内核层切换,效率高 无缓冲区,实时性好

适用场景 主要操作普通文件 普通文件、硬件设备类文件

标准IO的缓冲区分三种:

  • 行缓冲:默认1K,用在终端交互。遇到'\n'刷新、程序结束刷新、fflush强制刷新、缓冲区满刷新。

  • 全缓冲:默认4K,文件交互。程序结束刷新、文件关闭刷新、缓冲区满刷新、fflush强制刷新。

  • 无缓冲:0K,比如stderr,出错信息直接输出。

其他

几个格式化输出和字符串处理函数:

int printf(const char *format, ...);

int fprintf(FILE *stream, const char *format, ...);

fprintf把格式化后的字符串写入指定的文件流。

int dprintf(int fd, const char *format, ...);

dprintf写入到文件描述符代表的文件中。

int sprintf(char *str, const char *format, ...);

sprintf把格式化后的字符串写入字符数组,常用于字符串拼接、把整型或浮点型转成字符串。

char *strtok(char *str, const char *delim);

字符串截取函数。str是原始字符串,delim是分隔符。成功返回截取到的子字符串首地址,到末尾返回NULL。第一次调用传str,后续传NULL继续截取。

相关推荐
姚永强1 小时前
zabbix安装教学
笔记·zabbix
吃好睡好便好1 小时前
转换函数的使用
学习·matlab·生活·转换函数
Vcaker1 小时前
Linux学习22-openstack部署与使用
linux·运维·学习
XiHongShi20161 小时前
51单片机C语言版(1)
嵌入式硬件·学习·51单片机
智购科技自动贩卖机1 小时前
自动售货机嵌入式系统Go语言开发实践:从资源受限设备到RTOS协程调度的工程化之路
大数据·linux·数据库·人工智能·yolo·架构·golang
姓刘的哦2 小时前
STM32的启动流分析
linux·运维·arm开发
lhldsg2 小时前
课程排课系统实战指南:从数据库设计到算法调优全流程解析
java·数据库·算法·小程序
BSD_HY2 小时前
薄膜开关矩阵扫描电路设计中的防鬼键措施
人工智能·算法·矩阵·人机交互·薄膜开关·源头工厂·深圳工厂
linux-hzh2 小时前
百日算法修炼 · Day 17
数据结构·算法