linux c 文件操作
目录
一、简述
二、系统I/O
2.1 open()函数
2.2 close()函数
2.3 read()函数
2.4 write()函数
2.5 lseek()函数
2.6 mmap()函数
三、标准I/O
3.1 fopen()函数
3.2 fclose()函数
3.3 fread()函数
3.4 fwrite()函数
3.5 fseek()函数
3.6 ftell()函数
3.7rewind()函数
一、简述
记--Linux环境下C语言编程的文件操作。
两种操作文件的方式:
1、系统I/O:系统调用接口,open(), read(), write(), lseek(), close()。是操作系统直接提供的编程接口(API)。
2、标准/IO:标准库的I/O函数,fopen(), fread(), fwrite(), fseek(), fclose(),是对系统调用接口进一步封装。
系统I/O常用于硬件级别,可以设置读缓冲区,一般没有写缓冲区;
标准I/O常用于软件级别,自带读写缓冲区。
二、系统I/O
2.1 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 | 只写方式打开文件 | |||
O_RDWR | 读写方式打开文件 | |||
O_CREAT | 如果文件不存在,则创建该文件 | |||
O_TRUNC | 如文件已经存在,则删除文件中原有数据 | |||
O_APPEND | 以追加方式打开文件 | |||
mode | 如果文件被新建,指定其权限为mode(八进制表示法) | |||
返回值 | 成功 | 大于等于0 的整数(即文件描述符) | ||
失败 | -1,并且errno会被设置 |
补充说明:
1)flags 的各种取值可以用位或的方式叠加起来,例如创建文件的时候需要满足这样的
选项:读写方式打开,不存在要新建,如果存在了则清空。则flags 的取值应该是:O_RDWR | O_CREAT | O_TRUNC。
2)mode 是八进制权限,比如0644,或者0755 等。也可以是使用系统已定义的
S_IRWXU 00700 user (file owner) has read, write, and execute permission //用户可读写执行权限
S_IRUSR 00400 user has read permission//用户写权限
S_IWUSR 00200 user has write permission//用户写权限
S_IXUSR 00100 user has execute permission//用户执行权限 (更多选项可查询man手册:man 2 open)
比如新创建的文件权限只需要读写权限:S_IRUSR | S_IWUSR
3)文件描述符
其实是一个数组的下标值,在内核中打开的文件是用 file 结构体来表示的,每一个结构体都会有一个 指针来指向它们,这些指针被统一存放在一个叫做 fd_array 的数组当中,而这个数组被存 放在一个叫做 files_struct 的结构体中,该结构体是进程控制块 task_struct 的重要组成部分。
2.2 close()函数
功能 |
关闭文件并释放相应资源 |
|
头文件 |
#include <unistd.h> |
|
原型 |
int close(int fd); |
|
参数 | fd | 要关闭的文件的描述符 |
返回值 |
成功 |
0 |
失败 |
-1 |
|
备注 |
重复关闭一个已经关闭了的文件或者尚未打开的文件是安全的。 |
2.3 read()函数
功能 |
从指定文件中读取数据 |
|
头文件 |
#include <unistd.h> |
|
原型 |
ssize_t read(int fd, void *buf, size_t count); |
|
参数 |
fd |
从文件 fd 中读数据,(fd是某个文件的描述符) |
buf |
指向存放读到的数据的缓冲区,(就是放数据的内存首地址) | |
count |
想要从文件 fd 中读取的字节数 | |
返回值 |
成功 |
实际读到的字节数 |
失败 |
-1 |
|
备注 |
实际读到的字节数小于等于 count |
补充说明:
ssize_t :是类型重定义,为了跨平台兼容。比如说long在32位系统可能是4字节,64位系统可能是8字节,嵌入式开发有的只有16位,那么int只有2个字节。
但是在编程时往往需要根据类型大小来进行操作数据,例如在64位系统编程时8字节使用long类型,如果移植到32位系统时long只有4字节,那么就需要改动好多个地方,所以重定义一种类型,然后根据实际系统再指定,方便改动移植。例如:重定义ssize类型是8字节的,在32位系统,我可以将long long重定义为ssize类型,如果是64位系统可以定义为long类型,这样只需改动一处。
2.4 write()函数
功能 |
将数据写入指定的文件 |
||
头文件 |
#include <unistd.h> |
||
原型 |
ssize_t write(int fd, const void *buf, size_t count); |
||
参数 |
fd |
将数据写入到文件fd 中 (fd是某个文件的描述符) |
|
buf |
指向即将要写入的数据,(要写的数据的内存首地址) |
||
count |
要写入的字节数 |
||
返回值 |
成功 |
实际写入的字节数 |
|
失败 |
-1 |
||
备注 |
实际写入的字节数小于等于 count |
2.5 lseek()函数
功能 |
调整文件位置偏移量 |
|||
头文件 |
#include <sys/types.h> #include <unistd.h> |
|||
原型 |
off_t lseek(int fd, off_t offset, int whence); |
|||
参数 |
fd |
要调整位置偏移量的文件的描述符 |
||
offset |
相对基准点的偏移大小 |
|||
whence:基准点 |
SEEK_SET:文件开头处 |
|||
SEEK_CUR:当前位置 |
||||
SEEK_END:文件末尾处 |
||||
返回值 |
成功 |
新文件位置偏移量(相对于文件开头的偏移) |
||
失败 |
-1 |
|||
备注 |
可用 file-size= lseek(fd,0,SEEK_END);来测量文件大小 |
示例代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main(int argc,char* argv[])
{int fd;int wr_ret;int rd_ret;unsigned long file_size;char wr_buf[100] = "hello world";char rd_buf[100];fd = open("a.txt", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IROTH);//等价于fd = open("a.txt", O_RDWR | O_CREAT | O_TRUNC, 0x604);if(fd == -1){perror("open file error:");//只有上面的函数设置了error全局错误号,才可使用,会根据error输出对应的错误信息return -1;}printf("fd = %d\n", fd);wr_ret = write(fd, wr_buf, sizeof(wr_buf));if(wr_ret == -1){perror("write file error:");return -1;}printf("wr_ret = %d\n", wr_ret);lseek(fd, 0, SEEK_SET);//上面的写操作,文件位置偏移量也会相应的移动,此处将文件偏移到文件开始位置,然后才能读取刚刚输入的内容rd_ret = read(fd, rd_buf, sizeof(rd_buf));if(rd_ret == -1){perror("read file error:");return -1;}printf("rd_ret = %d\n",rd_ret);printf("content=%s\n", rd_buf);file_size = lseek(fd, 0, SEEK_END);printf("file_size = %lu\n", file_size);close(fd);//关闭文件return 0;
}
运行结果:
2.6 mmap()函数
功能 |
将物理内存映射为虚拟内存,为了提高效率。(比如将一个文件映射到虚拟内存,以操作内存的方式进行数据的读写,但是不会改变文件的大小,一般不用于普通文件) | ||
头文件 |
#include <sys/mman.h> | ||
原型 |
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset); | ||
参数 |
addr |
从虚拟内存的哪个地址开始去映射这片内存 NULL代表由系统决定映射起始地址 |
|
length | 映射的内存长度(字节为单位) | ||
port |
决定这块内存的操作权限,以下数值可以相或 PROT_READ Pages may be read. 读权限 PROT_WRITE Pages may be written. 写权限 PROT_NONE Pages may not be accessed. 无权限 |
||
flags |
操作标志 MAP_SHARED:在多进程中把这块内存共享给其他进程 MAP_PRIVATE:不共享内存 |
||
fd |
将数据写入到文件fd 中 (fd是某个文件的描述符) | ||
offset |
基于文件头偏移多少单位开始映射 | ||
返回值 |
成功 |
成功返回映射的虚拟地址 | |
失败 |
失败返回MAP_FAILED,其实就是个-1, errno会被设置 | ||
备注 |
取消映射 int munmap(void *addr, size_t length); 成功返回0,失败返回-1 |
更多请查看man手册:man 2 mmap
示例代码:
#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h> //mencpy()int main(void)
{int fd;char *map_ptr;int retval;fd = open("a.txt",O_RDWR);if(fd == -1){perror("open failed:");return -1;}map_ptr = mmap( NULL, 100, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);if(map_ptr == MAP_FAILED){perror("map memory failed:");return -1;}printf("%s", map_ptr);memcpy(map_ptr, "haha", 5);retval = munmap(map_ptr, 100);if(retval == -1){perror("munmap failed:");return -1;}close(fd);return 0;
}
运行结果:
三、标准I/O
3.1 fopen()函数
功能 |
获取指定文件的文件指针 |
|
头文件 |
#include <stdio.h> |
|
原型 |
FILE *fopen(const char *path, const char *mode); |
|
参数 |
path |
要打开的文件的路径名称 |
mode |
“r” : 以只读方式打开文件,要求文件必须存在。 | |
“r+” : 以读写方式打开文件,要求文件必须存在。 |
||
“w” : 以只写方式打开文件,文件如果不存在将会创建新文件,如果存 在将会将其内容清空。 |
||
“w+” : 以读写方式打开文件,文件如果不存在将会创建新文件,如果存在将会将其内容清空。 |
||
“a” : 以只写方式打开文件,文件如果不存在将会创建新文件,且文件位置偏移量被自动定位到文件末尾(即以追加方式写数据)。 |
||
“a+” : 以读写方式打开文件,文件如果不存在将会创建新文件,第一次用于写数据则文件位置偏移量被自动定位到文件末尾(即以追加方式写数据),如果第一次用于读数据,文件位置偏移位置会定位到文件开始。 |
||
返回值 |
成功 |
文件指针 |
失败 | NULL | |
备注 |
返回的文件指针是一种指向结构体 FILE{}的指针,文件描述符就被封装在FILE结构体里面 |
程序一开始默认打开3个文件
设备 |
文件描述符(int) |
文件指针(FILE *) |
|
标准输入设备(键盘) |
0 |
STDIN_FILENO |
stdin |
标准输出设备(屏幕) |
1 |
STDOUT_FILENO |
stdout |
标准出错设备(屏幕) |
2 |
STDERR_FILENO |
stderr |
3.2 fclose()函数
功能 |
关闭指定的文件并释放其资源 |
|
头文件 |
#include <stdio.h> |
|
原型 |
int fclose(FILE *fp); |
|
参数 |
fp |
即将要关闭的文件 |
返回值 |
成功 |
0 |
失败 |
EOF |
|
备注 |
fclose( )不能对一个文件重复关闭 |
3.3 fread()函数
功能 |
从指定文件读取若干个数据块 |
|
头文件 |
#include <stdio.h> |
|
原型 |
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); |
|
参数 |
ptr |
自定义缓冲区指针,(通俗的说就是要存放 读取出来的数据 的地方) |
size |
数据块大小 | |
nmemb |
数据块个数 | |
stream |
即将被读取数据的文件指针 | |
返回值 |
成功 |
读取的数据块个数,等于 nmemb |
失败 |
读取的数据块个数,小于 nmemb 或等于 0 |
|
备注 |
当返回小与 nmemb 时,文件 stream 可能已达末尾,或者遇到错误 |
3.4 fwrite()函数
功能 |
将若干块数据写入指定的文件 |
|
头文件 |
#include <sys/ioctl.h> |
|
原型 |
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream); |
|
参数 |
ptr:自定义缓冲区指针(要写入的数据的首地址) |
|
size:数据块大小 |
||
nmemb:数据块个数 |
||
stream:即将被写入数据的文件指针 |
||
返回值 |
成功 |
写入的数据块个数,等于 sinmembze |
失败 |
写入的数据块个数,小于 nmemb 或等于 0 |
|
备注 |
无 |
3.5 fseek()函数
功能 |
设置指定文件的当前位置偏移量 |
||
头文件 |
#include <sys/ioctl.h> |
||
原型 |
int fseek(FILE *stream, long offset, int whence); |
||
参数 |
stream:需要设置位置偏移量的文件指针 |
||
offset:新位置偏移量相对基准点的偏移 |
|||
whence:基准点 |
SEEK_SET:文件开头处 |
||
SEEK_CUR:当前位置 |
|||
SEEK_END:文件末尾处 |
|||
返回值 |
成功 |
0 |
|
失败 |
-1 |
||
备注 |
无 |
3.6 ftell()函数
功能 |
获取指定文件的当前位置偏移量 |
|
头文件 |
#include <sys/ioctl.h> |
|
原型 |
long ftell(FILE *stream); |
|
参数 |
stream:需要返回当前文件位置偏移量的文件指针 |
|
返回值 |
成功 |
当前文件位置偏移量 |
失败 |
-1 |
|
备注 |
无 |
3.7rewind()函数
功能 |
将指定文件的当前位置偏移量设置到文件开头处 |
头文件 |
#include <sys/ioctl.h> |
原型 |
void rewind(FILE *stream); |
参数 |
stream:需要设置位置偏移量的文件指针 |
返回值 |
无 |
备注 |
该函数的功能是将文件 strean 的位置偏移量置位到文件开头处。 |
简单例子:
#include <stdio.h>int main(int argc,char* argv[])
{int wr_ret;int rd_ret;FILE *fp;unsigned long file_size;char wr_buf[100] = "hello world";char rd_buf[100];fp = fopen( "a.txt", "a+" );//文件追加,可读可写,文件不存在则创建if(fp == NULL){perror("open file error:");//只有上面的函数设置了error全局错误号,才可使用,会根据error输出对应的错误信息return -1;}wr_ret = fwrite( wr_buf, sizeof(wr_buf), 1, fp);printf("wr_ret = %d\n", wr_ret);rewind(fp);//上面的写操作,文件位置偏移量也会相应的移动,此处将文件偏移到文件开始位置,然后才能读取刚刚输入的内容rd_ret = fread(rd_buf, sizeof(rd_buf), 1, fp);printf("rd_ret = %d\n",rd_ret);printf("content=%s\n", rd_buf);fseek(fp, 0, SEEK_END);file_size = ftell(fp);printf("file_size = %lu\n", file_size);fclose(fp);//关闭文件return 0;
}
运行结果
linux c 文件操作相关推荐
- linux修改目录block信息,linux下文件操作inode,block的变化
在"浅谈linux性能调优之三:分区格式化之前的考虑" http://my.oschina.net/sharelinux/blog/143522 一文中我说了inode与bl ...
- Linux的文件操作
1. 文件操作系统的调用 Linux的文件操作系统调用(在Windows编程领域,操作系统提供的接口称为 API)涉及创建(create).打开(open).读写(read/write)和关闭(clo ...
- Linux内核文件操作
Linux内核文件操作 前言 一.文件操作结构体 二.VFS之file_operations对象 1.文件打开filp_open 2.文件关闭filp_close 3.文件读取vfs_read 4.文 ...
- linux拷贝文件函数,linux下文件操作的各个函数
作者:HoytEmail:hoytluo@21cn.com 前言: 我们在这一节将要讨论linux下文件操作的各个函数. 文件的创建和读写 文件的各个属性 目录文件的操作 管道文件 --------- ...
- 服务器LINUX查看文件操作
LINUX查看文件操作 步骤命令如下: grep # 显示 key 所在行及前后5行grep -5 'key' filegrep -C 5 'key' file # 显示 key 所在行及前5行gre ...
- Linux C: 文件操作相关的系统调用
一.常见的文件操作相关的系统调用 普通权限的系统调用 函数 说明 int access(char *pathname,int mode) 检查对某个文件的权限 int chdir(const char ...
- linux c文件操作,Linux C 文件的输入/输出操作
10.1 文件I/O操作概述 在Linux系统中,文件I/O操作可以分为两类,一类是基于文件描述符的I/O操作,另一类是基于数据流的I/O操作. 10.1.1 文件描述符简介 在文件操作一章中,也经常 ...
- 【Linux】文件操作系统调用
一. 文件描述符 在Linux下使用文件描述符来表示设备文件和普通文件.文件描述符是一个整型的数据,所有对文件的操作都通过文件描述符实现.文件描述符的范围是0~OPEN_MAX,系统中有3个已经分配的 ...
- linux驱动文件操作简单介绍
1.设备号 主设备号标识设备对应的驱动程序,次设备号由内核使用,用于确定设备文件所指的设备. 通过次设备号获得一个指向内核设备的直接指针,也可将此设备号当作设备本地数组的索引. 设备编号用dev_t表 ...
最新文章
- 互联网大厂算法面试题集合,看完我跪了!
- pytorch 之 torch.eye()函数
- java中的双与_java 双冒号是什么操作符?
- controller接收json数据_SpringMVC实现多种数据类型绑定
- 微机原理和计算机组成原理一样吗_计算机组成原理:计算机的层次与编程语言...
- Vue-- $attrs与$listeners的详解
- 通过伙伴系统申请内核内存的函数有哪些?
- 在微信中调用ajax出现的问题
- 说几个打工人要避开的坑
- sql与mysql数据对接_SQL Server 对接MySQL 数据库
- 这才是程序员该有的桌面壁纸!
- VLAN tagged和untagged
- Motrix全能下载神器 无限制版 支持下载HTTP、磁力、FTP、BT、百度网盘等
- svn报错E175002
- 实战项目-小说网站开发过程中难点记录(1)
- Nginx 缓存配置
- 用户空间和内核空间的区别
- BlackArch 字典收集(wordlistctl)
- MotionEvent和TouchSlop
- java兔子繁殖总数_兔子繁殖问题即斐波那契数列的java实现