博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux 文件操作
阅读量:5218 次
发布时间:2019-06-14

本文共 5437 字,大约阅读时间需要 18 分钟。

一、open

#include 
#include
#include
int open(const char *pathname, int flags);int open(const char *pathname, int flags, mode_t mode);//返回值:成功返回新分配的文件描述符,出错返回-1并设置errno

open函数在C代码里面的实际声明为 int open(const char *pathname, int flags, ...);

其中flags的主先参数有,

  • O_RDONLY 只读打开

  • O_WRONLY 只写打开

  • O_RDWR 可读可写打开

这三个参数是相互排斥的,只能选其中之一,然后可以加上其他的附加参数

  • O_APPEND 表示追加。如果文件已有内容,这次打开文件所写的数据附加到文件的末尾而不覆盖原来的内容。

  • O_CREAT 若此文件不存在则创建它。使用此选项时需要提供第三个参数mode,表示该文件的访问权限。

  • O_EXCL 如果同时指定了O_CREAT,并且文件已存在,则出错返回。

  • O_TRUNC 如果文件已存在,并且以只写或可读可写方式打开,则将其长度截断(Truncate)为0字节。

  • O_NONBLOCK 对于设备文件,以O_NONBLOCK方式打开可以做非阻塞I/O(Nonblock I/O),非阻塞I/O在下一节详细讲解。

注意open函数与C标准I/O库的fopen函数有些细微的区别:

  • 以可写的方式fopen一个文件时,如果文件不存在会自动创建,而open一个文件时必须明确指定O_CREAT才会创建文件,否则文件不存在就出错返回。

  • ww+方式fopen一个文件时,如果文件已存在就截断为0字节,而open一个文件时必须明确指定O_TRUNC才会截断文件,否则直接在原来的数据上改写。

参数mode表示权限

注:关于linux的文件权限,参考

  每个linux 文件都有四种权限,可读r,可写w,可执行x(当为目录时,x 表示可以cd到此目录)和无权限。不同的用户类对同一个文件又享有不同的权限。文件用户分为所有者用户、所有者所属组用户、其他用户。

在shell下,输入 ls -l 命令,则会列出当前文件与目录

ls drwxr-xr-x 24 lynd lynd   4096 2012-09-29 16:32 soft-rw-r--r--  1 lynd lynd     50 2012-09-28 16:29 svn-commit.tmp

    每一行的开头如“drwxr-xr-x”、“-rw-r--r--”,第一位表示文件类型,-表示文件,d表示目录

    2-4位表示文件所有者的权限,u权限

    5-7位表示文件所有者所属组成员的权限,g权限
    8-10位表示所有者所属组之外的用户的权限,o权限   
    2-10位的权限总和有时称为a权限

所以,可以得出:

  soft是一个文件夹,所有者用户有全部的权限,所有者所属组用户有读与cd权限,其他用户则只有cd权限。

  svn-commit.tmp是一个文件,所有者用户有读写权限,所有者所属组用户有与其他用户只有读的权限。

文件权限的数字表示法: 将r、w和x分别用4、2、1来代表

 原始权限  转换为数字  数字表示法
 rwxrwxr-x  (421)(421)(401)  775
 rwxr-xr-x  (421)(401)(401)  755

 

  

 

回到mode参数,mode就是用来设置所创建文件的权限了,可以用八进制数表示,比如0644表示-rw-r--r--,也可以用S_IRUSRS_IWUSR等宏定义按位或起来表示

 但所使用的mode并不是最终的结果,而是与shell 的 umask 进行&~运算后的结果,如果比如umask为022,而mode为0777,那么最终结果为 -rwxr-xr-x

 

二、 read

#include 
ssize_t read(int fd, void *buf, size_t count);/*从打开的文件中读数据*/
返回值:成功返回读取的字节数,出错返回-1并设置errno,如果在调read之前已到达文件末尾,则这次read返回0

三、write

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

返回值:成功返回写入的字节数,出错返回-1并设置errno

四、seek

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

参数offsetwhence的含义和fseek的参数相同

五、fcntl改变已打开文件的属性

#include 
#include
int fcntl(int fd, int cmd);int fcntl(int fd, int cmd, long arg);int fcntl(int fd, int cmd, struct flock *lock);

例:

#include 
#include
#include
#include
#include
#define MSG_TRY "try again\n"int main(void){ char buf[10]; int n; int flags; flags = fcntl(STDIN_FILENO, F_GETFL); flags |= O_NONBLOCK; if (fcntl(STDIN_FILENO, F_SETFL, flags) == -1) { perror("fcntl"); exit(1); }tryagain: n = read(STDIN_FILENO, buf, 10); if (n < 0) { if (errno == EAGAIN) { sleep(1); write(STDOUT_FILENO, MSG_TRY, strlen(MSG_TRY)); goto tryagain; } perror("read stdin"); exit(1); } write(STDOUT_FILENO, buf, n); return 0;}

以下程序通过命令行的第一个参数指定一个文件描述符,同时利用Shell的重定向功能在该描述符上打开文件,然后用fcntlF_GETFL命令取出File Status Flag并打印。

#include 
#include
#include
#include
int main(int argc, char *argv[]){ int val; if (argc != 2) { fputs("usage: a.out
\n", stderr); exit(1); } if ((val = fcntl(atoi(argv[1]), F_GETFL)) < 0) { printf("fcntl error for fd %d\n", atoi(argv[1])); exit(1); } switch(val & O_ACCMODE) { case O_RDONLY: printf("read only"); break; case O_WRONLY: printf("write only"); break; case O_RDWR: printf("read write"); break; default: fputs("invalid access mode\n", stderr); exit(1); } if (val & O_APPEND) printf(", append"); if (val & O_NONBLOCK) printf(", nonblocking"); putchar('\n'); return 0;}

 

六、ioctl

ioctl用于传送控制信息,例如,在串口线上收发数据通过read/write操作,而串口的波特率、校验位、停止位通过ioctl设置,A/D转换的结果通过read读取,而A/D转换的精度和工作频率通过ioctl设置.

#include 
int ioctl(int d, int request, ...);

 

七、mmap

mmap可以把文件的一部分直接映射到内存,这样文件中的位置直接就有对应的内存地址,对文件的读写可以直接用指针来做而不需要read/write函数。(跟据我的经验,并不是所有的文件系统能够使用mmap,jffs2就不行)

#include 
void *mmap(void *addr, size_t len, int prot, int flag, int filedes, off_t off); int munmap(void *addr, size_t len);

如果addr参数为NULL,内核会自己在进程地址空间中选择合适的地址建立映射。如果addr不是NULL,则给内核一个提示,应该从什么地址开始映射,内核会选择addr之上的某个合适的地址开始映射。建立映射后,真正的映射首地址通过返回值可以得到。len参数是需要映射的那一部分文件的长度。off参数是从文件的什么位置开始映射,必须是页大小的整数倍(在32位体系统结构上通常是4K)。filedes是代表该文件的描述符。

prot参数有四种取值:

  • PROT_EXEC表示映射的这一段可执行,例如映射共享库

  • PROT_READ表示映射的这一段可读

  • PROT_WRITE表示映射的这一段可写

  • PROT_NONE表示映射的这一段不可访问

flag参数有很多种取值,这里只讲两种,其它取值可查看mmap(2)

  • MAP_SHARED多个进程对同一个文件的映射是共享的,一个进程对映射的内存做了修改,另一个进程也会看到这种变化。

  • MAP_PRIVATE多个进程对同一个文件的映射不是共享的,一个进程对映射的内存做了修改,另一个进程并不会看到这种变化,也不会真的写到文件中去。

如果mmap成功则返回映射首地址,如果出错则返回常数MAP_FAILED。当进程终止时,该进程的映射内存会自动解除,也可以调用munmap解除映射。munmap成功返回0,出错返回-1。

#include 
#include
#include
int main(void){ int *p; int fd = open("hello", O_RDWR); if (fd < 0) { perror("open hello"); exit(1); } p = mmap(NULL, 6, PROT_WRITE, MAP_SHARED, fd, 0); if (p == MAP_FAILED) { perror("mmap"); exit(1); } close(fd); p[0] = 0x30313233; munmap(p, 6); return 0;}

上面的例子也说明,文件关闭之后,并不影响mmap的使用,而munmap才能关闭mmap

 

 

 

 

转载于:https://www.cnblogs.com/lynd/archive/2012/10/23/2731753.html

你可能感兴趣的文章
IE11兼容IE8的设置
查看>>
windows server 2008 R2 怎么集成USB3.0驱动
查看>>
Foxmail:导入联系人
查看>>
vue:axios二次封装,接口统一存放
查看>>
vue中router与route的区别
查看>>
js 时间对象方法
查看>>
网络请求返回HTTP状态码(404,400,500)
查看>>
Spring的JdbcTemplate、NamedParameterJdbcTemplate、SimpleJdbcTemplate
查看>>
Mac下使用crontab来实现定时任务
查看>>
303. Range Sum Query - Immutable
查看>>
图片加载失败显示默认图片占位符
查看>>
【★】浅谈计算机与随机数
查看>>
[转载]宇宙文明等级的划分标准
查看>>
《代码阅读方法与实现》阅读笔记一
查看>>
解决 sublime text3 运行python文件无法input的问题
查看>>
javascript面相对象编程,封装与继承
查看>>
Atlas命名空间Sys.Data下控件介绍——DataColumn,DataRow和DataTable
查看>>
Java中正则表达式的使用
查看>>
算法之搜索篇
查看>>
新的开始
查看>>