文件共享

一个进程打开了两个文件

文件表条目(file-table-entry):

1.文件状态标志(file-status-flags): 读/写/追加/同步/非阻塞等;

2.当前文件偏移量

3.v节点指针

//验证
int main(int argc, char *argv[])
{int fd1 = open("test.txt", O_RDONLY);if (fd1 == -1)err_exit("fd1 open O_RDONLY error");int fd2 = open("test.txt", O_RDWR);if (fd2 == -1)err_exit("fd2 open O_RDWR error");//读取fd1char buf[BUFSIZ];if (read(fd1, buf, 10) == -1)err_exit("read fd1 error");cout << "fd1: " << buf << endl;//读取fd2bzero(buf, 10);if (read(fd2, buf, 10) == -1)err_exit("read fd1 error");cout << "fd2: " << buf << endl;lseek(fd1, 0, SEEK_SET);lseek(fd2, 0, SEEK_SET);write(fd2, "Helloworld", 10);bzero(buf, 10);if (read(fd1, buf, 10) == -1)err_exit("read fd1 error");cout << "after fd2 write: " << buf << endl;
}

两个独立的进程打开同一个文件

复制文件描述符

方法有三种:

1.dup

2.dup2

#include <unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);
//示例
int main(int argc, char *argv[])
{int fd = open("text.txt", O_WRONLY|O_TRUNC);if (fd == -1)err_exit("open O_WRONLY error");//    close(1);   //将标准输出关闭, 则文件描述符1将空闲
//    int dupfd = dup(fd);int dupfd = dup2(fd, 1);cout << "dupfd = " << dupfd << endl;
}
/** 示例: 实现文件拷贝
其中execlp会在后面介绍
**/
int main(int argc, char *argv[])
{if (argc < 3)err_quit("usage: ./main file-name1 file-name2");close(STDIN_FILENO);open(argv[1], O_RDONLY);close(STDOUT_FILENO);open(argv[2], O_WRONLY|O_CREAT, 0666);execlp("/bin/cat", "cat", NULL);err_exit("execlp error");
}

3.fcntl

int fcntl(int fd, F_DUPFD, ... /* arg */ );
//示例见下

fcntl

#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );

操纵文件描述符, 改变已经打开的文件的属性

fcntl常用操作(cmd常用取值)

F_DUPFD (long)

复制文件描述符

F_GETFD (void)

F_SETFD (long)

文件描述符标志

F_GETFL (void)

F_SETFL (long)

文件状态标志

F_GETLK

F_SETLK,F_SETLKW(阻塞)

文件锁

//示例: 复制文件描述符
int main(int argc, char *argv[])
{int fd = open("text.txt", O_WRONLY|O_TRUNC);if (fd == -1)err_exit("open O_WRONLY error");close(1);   //将标准输出关闭, 则文件描述符1将空闲// 当cmd使用F_DUPFD时, 第三个参数代表搜索的起始位置int dupfd = fcntl(fd, F_DUPFD, 1);  // 1代表: 从1开始搜索一个空闲的文件描述符if (dupfd < 0)err_exit("fcntl F_DUPFD error");cout << "dupfd = " << dupfd << endl;
}

文件状态标志

F_GETFL (void)

Get the file access mode and the file status flags; arg is ignored.

F_SETFL (int)

Set the file status flags to  the  value  specified  by  arg.   File  access  mode(O_RDONLY,  O_WRONLY,  O_RDWR)  and  file  creation  flags (i.e., O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC) in arg are ignored.  On Linux this command can change only  the O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, and O_NONBLOCK flags.

//示例: 给文件描述符0设置成非阻塞模式
int main(int argc, char *argv[])
{int flags = fcntl(0, F_GETFL, 0);if (flags == -1)err_exit("fcntl get error");flags |= O_NONBLOCK;if (fcntl(0, F_SETFL, flags) == -1)err_exit("fcntl set error");char buf[BUFSIZ];if (read(0, buf, sizeof(buf)) == -1)err_exit("read STDIN_FILENO error");cout << "buffer size = " << strlen(buf) << endl;cout << buf << endl;
}
//示例: 文件状态设置与清除(函数封装)
void set_fl(int fd, int setFlag)
{int flags = fcntl(fd, F_GETFL, 0);if (flags == -1)err_exit("fcntl get flags error");//设置状态flags |= setFlag;if (fcntl(fd, F_SETFL, flags) == -1)err_exit("fcntl set flags error");
}
void clr_fl(int fd, int clrFlag)
{int flags = fcntl(fd, F_GETFL, 0);if (flags == -1)err_exit("fcntl get flags error");//清除状态flags &= ~clrFlag;if (fcntl(fd, F_SETFL, flags) == -1)err_exit("fcntl set flags error");
}//测试
int main(int argc, char *argv[])
{set_fl(0, O_NONBLOCK);clr_fl(0, O_NONBLOCK);char buf[BUFSIZ];if (read(0, buf, sizeof(buf)) == -1)err_exit("read STDIN_FILENO error");cout << "buffer size = " << strlen(buf) << endl;cout << buf << endl;
}

文件锁

F_SETLK (struct flock *)

Acquire  a lock (when l_type is F_RDLCK or F_WRLCK) or release a lock (when l_type is F_UNLCK) on the bytes specified by the l_whence, l_start, and l_len  fields  of lock.   If a conflicting lock is held by another process, this call returns -1 and sets errno to EACCES or EAGAIN.

F_SETLKW (struct flock *) 如果加锁不成功:会一直阻塞直到解锁

As for F_SETLK, but if a conflicting lock is held on the file, then wait for  that lock to be released.  If a signal is caught while waiting, then the call is interrupted and (after the signal  handler  has  returned)  returns  immediately  (with return value -1 and errno set to EINTR; see signal(7)).

F_GETLK (struct flock *)

On  input  to this call, lock describes a lock we would like to place on the file.

If the lock could be placed, fcntl() does  not  actually  place  it,  but  returns F_UNLCK  in  the l_type field of lock and leaves the other fields of the structure unchanged.  If one or more  incompatible  locks  would  prevent  this  lock  being placed,  then  fcntl()  returns  details  about  one of these locks in the l_type, l_whence, l_start, and l_len fields of lock and sets l_pid to be the  PID  of  the process holding that lock.

//文件锁结构体
struct flock
{...short l_type;    /* Type of lock: F_RDLCK,F_WRLCK, F_UNLCK */short l_whence;  /* How to interpret l_start:SEEK_SET, SEEK_CUR, SEEK_END */off_t l_start;   /* Starting offset for lock */off_t l_len;     /* Number of bytes to lock */pid_t l_pid;     /* PID of process blocking our lock(F_GETLK only) */...
};

注意: Specifying 0 for l_len has the special meaning: lock all bytes starting  at

the  location  specified  by l_whence and l_start through to the end of file,

no matter how large the file grows.

//示例1
int main(int argc, char *argv[])
{int fd = open("test.txt", O_RDWR|O_CREAT|O_TRUNC, 0666);if (fd == -1)err_exit("open file error");struct flock lock;lock.l_type = F_WRLCK;  //设定独占锁lock.l_whence = SEEK_SET;lock.l_start = 0;lock.l_len = 0; //锁定全部文件//if (fcntl(fd, F_SETLK, &lock) == 0)   //对比下面if (fcntl(fd, F_SETLKW, &lock) == 0){cout << "file lock success, press any key to unlock..." << endl;cin.get();lock.l_type = F_UNLCK;lock.l_whence = SEEK_SET;lock.l_start = 0;lock.l_len = 0;if (fcntl(fd, F_SETLK, &lock) == -1)err_exit("file unlock error");elsecout << "file unlock success" << endl;}elseerr_exit("file lock error");
}
//示例2: 打印加锁进程号
int main(int argc, char *argv[])
{int fd = open("test.txt", O_RDWR|O_CREAT|O_TRUNC, 0666);if (fd == -1)err_exit("open file error");struct flock lock;lock.l_type = F_WRLCK;  //设定独占锁lock.l_whence = SEEK_SET;lock.l_start = 0;lock.l_len = 0; //锁定全部文件if (fcntl(fd, F_SETLK, &lock) == 0){cout << "file lock success, press any key to unlock..." << endl;cin.get();lock.l_type = F_UNLCK;lock.l_whence = SEEK_SET;lock.l_start = 0;lock.l_len = 0;if (fcntl(fd, F_SETLK, &lock) == -1)err_exit("file unlock error");elsecout << "file unlock success" << endl;}else    //如果失败, 则获取锁信息{if (fcntl(fd, F_GETLK, &lock) == -1)err_exit("get lock error");cout << "lock process: " << lock.l_pid << endl;if (lock.l_type == F_WRLCK)cout << "type: F_WRLCK" << endl;elsecout << "type: F_RDLCK" << endl;if (lock.l_whence == SEEK_SET)cout << "whence: SEEK_SET" << endl;else if (lock.l_whence == SEEK_END)cout << "whence: SEEK_END" << endl;elsecout << "whence: SEEK_CUR" << endl;}
}

文件I/O实践(3) --文件共享与fcntl相关推荐

  1. Linux操作与管理文件(多次打开同一文件,文件共享,fcntl函数,标准IO库)

    1.linux系统如何管理文件 硬盘中的静态文件和inode: (1)硬盘分为两大区域:一个是硬盘内容管理表项,另一个是真正存储内容的区域.先去读取硬盘内容管理表,找到要访问的存储内容的区域,再用得到 ...

  2. 云服务器文件做共享,云服务器文件共享

    云服务器文件共享 内容精选 换一换 本节操作指导用户实现同一个子网的Windows弹性云服务器之间文件共享.共享文件的云服务器在同一个子网下,且网络互通.在云服务器右下方的网络图标处,右键单击&quo ...

  3. python文件读取写入实践_python文件写入实例分析

    本文实例讲述了python文件写入的用法.分享给大家供大家参考.具体分析如下: Python中wirte()方法把字符串写入文件,writelines()方法可以把列表中存储的内容写入文件. f=fi ...

  4. jenkins修改pom文件_动手实践:美化 Jenkins 报告插件的用户界面

    对于 Jenkins 而言,可使用插件来可视化各种构建步骤的结果.有一些插件可用于呈现测试结果.代码覆盖率.静态分析等.这些插件通常都会获取给定构建步骤的构建结果,并在用户界面中显示它们.为了呈现这些 ...

  5. new file会创建文件吗_Rust 文件系统处理之文件读写 Rust 实践指南

    Rust 中,文件读写处理简单而高效.代码也很紧凑,容易阅读.我们从读取文件的字符串行.避免读取写入同一文件.使用内存映射随机访问文件这三个文件处理中的典型案例来了解一下. 文件处理场景大家都很熟悉, ...

  6. 文件I/O实践(2) --文件stat

    功能:获取文件元数据 #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int st ...

  7. 文件I/O实践(1) --基础API

    什么是I/O 输入/输出是内存和外设之间拷贝数据的过程: 设备->内存: 输入操作 内存->设备: 输出操作 高级I/O: ANSI C提供的标准I/O库函数成为高级I/O, 也称为带缓冲 ...

  8. 【环境搭建001】ubuntu 和 win7 在vm 下的文件夹共享实践

    ubuntu 和 win7 是vm下linux开发最常用的搭配了. 方法 1: 1. 选择VMware Workstation程序菜单中Virtual Machine Settings-->Op ...

  9. go 计算文件sha-256_Kubernetes入门实践--部署运行Go项目

    以下文章来源于网管叨bi叨 ,作者KevinYan11 介绍 今天的文章我准备和大家一起一步步地尝试做一个Go应用程序的Docker镜像,把它部署到Minikuebe上运行.今天的文章不需要什么基础, ...

最新文章

  1. 推荐10款优秀的JavaScript Web UI库 框架和套件
  2. 斯坦福CS231n 2017最新课程:李飞飞详解深度学习的框架实现与对比
  3. 一切苦恼的都是本质上由于能力不够
  4. 调整了canvas的高度页面变化后还原_Python GUI编程入门(25)-移动Canvas对象
  5. docker安装mysql远程不能访问,虚拟机中docker安装mysql远程无法访问解决方法
  6. mst算法matlab_基于并查集+Kruskal算法的matlab程序及最小生成树绘图
  7. 4.8地铁查询开发进度
  8. 体感俄罗斯方块,CPU就能跑,全开源
  9. 燕山大学计算机考研专硕专业课,燕山大学(专业学位)计算机技术研究生考试科目和考研参考书目...
  10. centos7 mysql5.6.35_Centos7.2.1511 编译安装Mysql5.6.35
  11. Jenkins 用户文档(运行多个步骤)
  12. python you-get ffmpeg 下载哔哩哔哩视频
  13. 如何抢到腾讯云校园1元优惠资格(新版腾讯云)-更新
  14. java发布帖子_第一篇发在javaeye的帖子
  15. 一阶系统开环传递函数表达式_自动控制总结:第五章、线性系统的校正方法
  16. 百度 谷歌 Twitter,这么多短链接服务(Short Url)到底哪家强?
  17. 金蝶云苍穹笔记(四)
  18. CompletableFuture学习
  19. 光纤布线系统的设计与检测(二)
  20. JFrog制品库的Aql语句

热门文章

  1. [Python]网络爬虫(九):百度贴吧的网络爬虫(v0.4)源码及解析
  2. 面试题55 - I. 二叉树的深度
  3. NDR(网络威胁检测及响应)与NTA的区别(网络流量检测)
  4. VS中CString与char型数组相互转换问题
  5. Linux进阶之软件管理
  6. 前端笔记之ES678WebpackBabel(上)初识ES678Babellet和const解构语法
  7. HBase读写的几种方式(一)java篇
  8. Poj_1325 Machine Schedule -最大匹配性质题目
  9. Xcode5 使用gitHub上库的SSH地址建立Repository,以及如何通过Xcode把代码传到GitHub
  10. java xml数据解析_java xml解析,数据读取