目录

一、简述

二、系统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_EXEC  Pages may be executed.  执行权限

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);
    addr:映射的起始地址
    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 文件操作相关推荐

  1. linux修改目录block信息,linux下文件操作inode,block的变化

    在"浅谈linux性能调优之三:分区格式化之前的考虑" http://my.oschina.net/sharelinux/blog/143522    一文中我说了inode与bl ...

  2. Linux的文件操作

    1. 文件操作系统的调用 Linux的文件操作系统调用(在Windows编程领域,操作系统提供的接口称为 API)涉及创建(create).打开(open).读写(read/write)和关闭(clo ...

  3. Linux内核文件操作

    Linux内核文件操作 前言 一.文件操作结构体 二.VFS之file_operations对象 1.文件打开filp_open 2.文件关闭filp_close 3.文件读取vfs_read 4.文 ...

  4. linux拷贝文件函数,linux下文件操作的各个函数

    作者:HoytEmail:hoytluo@21cn.com 前言: 我们在这一节将要讨论linux下文件操作的各个函数. 文件的创建和读写 文件的各个属性 目录文件的操作 管道文件 --------- ...

  5. 服务器LINUX查看文件操作

    LINUX查看文件操作 步骤命令如下: grep # 显示 key 所在行及前后5行grep -5 'key' filegrep -C 5 'key' file # 显示 key 所在行及前5行gre ...

  6. Linux C: 文件操作相关的系统调用

    一.常见的文件操作相关的系统调用 普通权限的系统调用 函数 说明 int access(char *pathname,int mode) 检查对某个文件的权限 int chdir(const char ...

  7. linux c文件操作,Linux C 文件的输入/输出操作

    10.1 文件I/O操作概述 在Linux系统中,文件I/O操作可以分为两类,一类是基于文件描述符的I/O操作,另一类是基于数据流的I/O操作. 10.1.1 文件描述符简介 在文件操作一章中,也经常 ...

  8. 【Linux】文件操作系统调用

    一. 文件描述符 在Linux下使用文件描述符来表示设备文件和普通文件.文件描述符是一个整型的数据,所有对文件的操作都通过文件描述符实现.文件描述符的范围是0~OPEN_MAX,系统中有3个已经分配的 ...

  9. linux驱动文件操作简单介绍

    1.设备号 主设备号标识设备对应的驱动程序,次设备号由内核使用,用于确定设备文件所指的设备. 通过次设备号获得一个指向内核设备的直接指针,也可将此设备号当作设备本地数组的索引. 设备编号用dev_t表 ...

最新文章

  1. 互联网大厂算法面试题集合,看完我跪了!
  2. pytorch 之 torch.eye()函数
  3. java中的双与_java 双冒号是什么操作符?
  4. controller接收json数据_SpringMVC实现多种数据类型绑定
  5. 微机原理和计算机组成原理一样吗_计算机组成原理:计算机的层次与编程语言...
  6. Vue-- $attrs与$listeners的详解
  7. 通过伙伴系统申请内核内存的函数有哪些?
  8. 在微信中调用ajax出现的问题
  9. 说几个打工人要避开的坑
  10. sql与mysql数据对接_SQL Server 对接MySQL 数据库
  11. 这才是程序员该有的桌面壁纸!
  12. VLAN tagged和untagged
  13. Motrix全能下载神器 无限制版 支持下载HTTP、磁力、FTP、BT、百度网盘等
  14. svn报错E175002
  15. 实战项目-小说网站开发过程中难点记录(1)
  16. Nginx 缓存配置
  17. 用户空间和内核空间的区别
  18. BlackArch 字典收集(wordlistctl)
  19. MotionEvent和TouchSlop
  20. java兔子繁殖总数_兔子繁殖问题即斐波那契数列的java实现

热门文章

  1. JS中NaN、NULL、undefined、详解
  2. RIP基于跳数的负载均衡
  3. c# 18位身份证源代码
  4. J2ME游戏引擎程序结构
  5. linux redhat 下载_使用Vmware创建Linux(Ubuntu)系统
  6. IPv6 — Multi-homing(多宿主/多链路/多归属)
  7. 数据结构 — 平衡二叉树
  8. altium designer学习记录
  9. 颜色传感器TCS230的使用
  10. NR 5G 世界通信发展史简述