1.       文件的打开与创建

1.1   函数原型

#include <fcntl.h>

int open(const char *filename, int oflag, …/*[mode_t mode*/];

1.2   重要说明

oflag:只能为如下三个值:O_RDONLY O_WRONLY O_RDWR

读方式打开文件/etc/passwd

int fno;

if((fno = open(“/etc/passwd”, O_RDONLY)) >= 0)/*文件打开成功*/

755访问权限创建文件”/tmp/t1”, 如果文件存在则直接返回。

if((fno = open(“/tmp/t1”, O_WRONLY|O_CREAT|O_EXCL, 0755)) < 0) return;

计算文件的权限:

例如:假设Unix系统的umask值为0033, open函数创建权限为0666的文件,则最终创建文件的权限是?

计算过程如下:

mode = 110 110 110

~mask= 111 100 100

mod & (~mask) = 110 100 100 = 0644

PS:不可用mode – umask = 0633

2.       文件的关闭与删除

2.1   函数原型

#include <unistd.h>

int close(int fildes);

int unlink(char *path);//文件链接数减1,仅当文件链接数为0时,文件才真正删除

2.2   例子

PS:只使用一次的临时文件,可以先删除再使用,这样就不心担心忘记删除文件而造成磁盘垃圾文件了

#include <stdio.h>

#include <fcntl.h>

int main()

{

int foo;

if((foo = open("./tmpfile", O_RDWR | O_CREAT | O_EXCL, 0755)) < 0)

{

fprintf(stderr, "open file error!/n");

return;

}

    unlink("./tmpfile");

sleep(10);

printf("end./n");

}

3.       文件读、写、定位与缓冲

3.1   函数原型

#include <unistd.h>

ssize_t read(int filedes, void *buff, size_t nbytes);

ssize_t write(int filedes, void *buff, size_t nbytes);

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

int fsync(int fildes);//将所有写入文件描述符的数据真正写到磁盘或者其他设备中,类似于标准文件编程库中的函数fflush,成功时返回0,否则返回-1.

4.       文件控制

4.1   函数fcntl

管理文件低级操作,对已经打开的文件描述符进行各种控制操作,其原型如下:

#include <fcntl.h>

int fcntl(int fildes, int cmd);

int fcntl(int fildes, int cmd, int arg);

int fcntl(int fildes, int cmd, struct flock *arg);

函数fcntl对文件描述符fildes执行各种控制命令,参数cmd确定了执行具体命令和是否需要第三个附加参数“arg”。

4.2   文件锁

进程在操作文件期间,可以使用文件锁,锁定文件中的敏感部分,防止其他进程越权操作该部分数据。函数fcntl提供了对文件任意区域置锁的能力,既可以锁住全部文件,又可以锁住文件部分的记录,故文件锁又称为“记录锁”。

根据文件锁的访问方式,可以区分为读锁和写锁两种。读锁又名共享锁,它防止进程读取文件记录被更改。文件记录可以同时设置多个读锁,但当一个读锁存在时,就不能在记录处设置写锁。

写锁又名互斥锁,它用来保证文件更改记录时不被干扰,确保文件内容一致性和完整性,防止写丢失和读“脏”数据。文件记录一旦被设置了写锁,就不能再设置任意锁,除非写锁解除。

文件记录在同一刻,可以设置多个读锁,但仅能设置一个写锁,并且读、写锁不能同时存在。

struct flock

{

short l_type;//锁类型:F_RDLCK、F_WRLCK和F_UNLCK

short l_whence;//SEEK_SET、SEEK_CUR和SEEK_END

long l_start;

long l_len;//锁区域长度,0表示锁至全部文件

short l_pid;//拥有锁进程ID号

}

例如:为了锁住全部文件,应该如何设置flock结构?

答:

l_start=0;

l_len=0;

l_whence=SEEK_SET;

函数fcntl专用于锁操作时,参数cmd三种取值:

1.       F_GETTLK

获取对应文件中指定区域的文件锁信息

2.       F_SETFLK

设置文件锁,包括读锁、写锁和清除锁。

3.       F_SETLKW

为F_SETFLK的阻塞版本。

PS:文件锁最典型应用于两个方面,一是锁定文件中的临界数据,比如并发投票时文件记录投票数;二是利用具有互斥性质的写锁,实现进程的并发控制。

4.3   文件锁操作

1.       测试锁

/**

*SeeLock:查询描述符fd对应文件从偏移start处开始的len字节中的锁信息。

*/

void SeeLock(int fd, int start, int len)

{

struct flock arg;

arg.l_type = F_WRLCK;

arg.l_whence = SEEK_SET;

arg.l_start = start;

arg.l_len = len;

if(fcntl(fd, F_GETLK, &arg) == -1)

fprintf(stderr, "See Lock failed/n");

else if(arg.l_type == F_UNLCK)

fprintf(stderr, "No lock From %d To %d/n", start, len);

else if(arg.l_type == F_WRLCK)

fprintf(stderr, "Write Lock From %d To %d, id=%d/n", start, len, arg.l_pid);

else if(arg.l_type == F_RDLCK)

fprintf(stderr, "Read Lock From %d To %d, id=%d/n", start, len, arg.l_pid);

}

2.       申请读锁

/**

*GetReadLock(int fd, int start, int len)

*本函数以阻塞模式在文件描述符fd对应的文件中申请共享锁,锁定的区域为从偏移start处开始的len字节。

*/

void GetReadLock(int fd, int start, int len)

{

struct flock arg;

arg.l_type = F_RDLCK;

arg.l_whence = SEEK_SET;

arg.l_start = start;

arg.l_len = len;

if(fcntl(fd, F_SETLKW, &arg) == -1)

fprintf(stderr, "[%d] Set Read Lock failed./n", getpid());

else

fprintf(stderr, "[%d] Set Read Lock From %d To %d/n", getpid(), start, len);

}

3.       申请写锁

/**

*本函数以阻塞模式在文本描述符fd对应的文件中申请互斥写锁,锁定的区域为从偏移start处开始的len字节

*

*/

void GetWriteLock(int fd, int start, int len)

{

struct flock arg;

arg.l_type = F_WRLCK;

arg.l_whence = SEEK_SET;

arg.l_start = start;

arg.l_len = len;

if(fcntl(fd, F_SETLKW, &arg) == -1)

fprintf(stderr, "[%d] Set Write Lock failed./n", getpid());

else

fprintf(stderr, "[%d] Set Write Lock From %d To %d/n", getpid(), start, len);

}

4.       释放锁

/**

*本函数文件描述符fd对应文件中的释放锁,释放的区域为从偏移start处开始的len字节

*

*/

void ReleaseLock(int fd, int start, int len)

{

struct flock arg;

arg.l_type = F_UNLCK;

arg.l_whence = SEEK_SET;

arg.l_start = start;

arg.l_len = len;

if(fcntl(fd, F_SETLKW, &arg) == -1)

fprintf(stderr, "[%d] UnLock failed./n", getpid());

else

fprintf(stderr, "[%d] UnLock From %d To %d/n", getpid(), start, len);

}

5.       实例

int main()

{

int fd;

struct flock arg;

if((fd = open("/tmp/tlock1", O_RDWR | O_CREAT, 0755)) < 0)

{

fprintf(stderr, "open file failed!/n");

return -1;

}

SeeLock(fd, 0, 30);

GetReadLock(fd, 0, 10);      //申请读锁

SeeLock(fd, 11, 20);

GetWriteLock(fd, 11, 20);  //申请写锁

sleep(30);

ReleaseLock(fd, 0, 10);    //释放锁

ReleaseLock(fd, 11, 20);

return 0;

}

转载于:https://my.oschina.net/fuyajun1983cn/blog/263881

专题5 低级文件编程相关推荐

  1. 专题 7 设备文件编程

    1.       设备文件操作 UNIX对设备文件的操作相对简单,一般分为打开设备文件.设置设备文件.读写设备文件和关闭设备文件等几部分. 代码示例如下: fd = open(devname, O_R ...

  2. 专题 6 目录文件编程

    1.       对目录文件的操作包括创建.打开.定位和删除等内容, 其中 (1)       获取工作目录的函数有getcwd和getwd等. (2)       设置工作目录的函数有chdir和f ...

  3. 手机c语言多文件编程,C语言多文件编程

    今天,IT培训网小编为大家总结的是C语言,C语言多模块开发(多文件编程). 目前为止,我们编写的大部分C语言程序都只包含一个源文件,没有将代码分散到多个模块中,对于只有几百行的小程序来说这或许可以接受 ...

  4. [Linux系统编程]_文件编程(一)

    嵌入式之路,贵在日常点滴 ---阿杰在线送代码 目录 一.系统调用 1.1 什么是系统调用 1.2 什么是库函数 1.3 将hello写入到文件1.txt流程 1.4 为什么要有缓冲区(补充) 1.5 ...

  5. Linux基础之文件编程

    文件编程篇 一:文件的打开及创建 二:文件写入操作 三:文件读取操作和文件光标移动操作 四:文件打开创建的补充 五:文件操作原理概述 六:文件操作小应用之实现cp指令 七:文件编程小应用之修改程序的配 ...

  6. C语言模块化开发,深入多文件编程

    目录 文章目录 目录 多文件编程 项目分割 避免命名冲突 项目生成的过程 预处理 编译 汇编 链接 语言发展的过程 机器语言 汇编语言 C语言 高级语言 编译的本质 目标文件里藏着什么 可执行文件 链 ...

  7. linux应用程序接收文件,Linux应用程序学习之文件编程

    Linux应用程序学习之文件系统调用函数编程 上一篇我们了解了Linux系统下函数库的设计方法,这一章我们就来学习一下linux系统下常用的文件操作函数,在进行系统文件操作函数介绍前,我们首先要明白一 ...

  8. linux判断文件写入完毕,linux文件编程——系统调用(打开、写入、读取、访问判断)...

    linux文件编程有两个方法:1.linux系统调用 2.C语言函数库 前者依赖的是linux系统,后者独立于操作系统而存在,不依赖于任何操作系统,因此,在不同的操作用使用C语言函数库的方法是一样的. ...

  9. linux文件编程(1)—— open、write、read、lseek、阻塞问题

    参考:linux文件编程(1)-- 常用API之open.write.read.lseek 作者:丶PURSUING 发布时间: 2021-04-08 22:19:28 网址:https://blog ...

最新文章

  1. golang beego orm报错 must have one register DataBase alias named `default` 解决方案
  2. iOS-改变UITextField的Placeholder颜色的三种方式
  3. 047_Object对象
  4. 卡巴斯基授权许可文件_安全许可证的申请流程有哪些?
  5. Zookeeper的一次迁移故障
  6. Python入门学习笔记(4)
  7. [Java设计模式]单例模式
  8. win7资源监视器介绍
  9. 一只测试喵的重新启航
  10. C#人事工资管理系统
  11. EXTJS开发过程遇到的一些问题的小结(转自麦田守望者)
  12. 2021十大手表品牌TOP排行榜
  13. hbuilder运行uniapp,微信开发者工具打开但没有运行项目
  14. 苹果手机怎么备份所有数据_ORICO手机备份宝,数据备份更轻松
  15. C++——求平均数、求和函数
  16. 【软考|软件设计师】专业英语(软考真题)
  17. HJ7 取近似值(重点关注)
  18. 用c语言编写s7-1200 plc程序教程,S7-1200编程指南.pdf
  19. 廖雪峰Python教程笔记(一)
  20. 【Python爬虫系列】为什么我喜欢python?来看看这些让人爱不释手的原因吧,购物网站大盘点,看过这些python做的项目,我立马入坑了…(神奇 | 爱了,爱了)

热门文章

  1. 网络信息安全之防火墙的设计 (三)
  2. 8.VMware View 4.6安装与部署-connection server(View Transfer Server)
  3. free命令输出详解
  4. RIM 将在今天发布新的 BlackBerry 7 OS 手机
  5. JDBC 2.0中的高级数据类型
  6. 软件测试2019:第四次作业
  7. zabbix监控nginx,PHP-FPM,ELK报警
  8. 哈希表建立及冲突处理
  9. 第九章 Shell信号发送与捕捉
  10. SRM遇到的一个数论技巧——最大公约数和最小公倍数的关系