系统编程--文件IO
1.文件描述符
文件描述符是一个非负整数,当打开一个现有文件或创建一个新文件时候,内核向进程返回一个文件描述符,新打开文件返回文件描述符表中未使用的最小文件描述符。Unix系统shell使用文件描述符0与进程的标准输入相关联,文件描述符1与进程的标准输出相关联,文件描述符2与进程的标准出错相关联,在POSIX标准中,幻数0、1、2应当替换为符号常量STDIN_FILENO、STDOUT_FILENO和STDERR_FILENO
Linux最大打开文件描述符数 cat /proc/sys/fs/file-max 或者 ulimit -n
#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);
#include <fcnt1.h>
int create(const char *pathname,mode_t mode);
此函数等效于
int open(pathname,O_WRONLY | O_CREAT | O_TRUNC,mode);
4.close函数
#include<fcnt1.h>
int close (int filedes); //返回值若成功返回0不成功返回-1
#include<unistd.h>
off_t lseek(int fileds,off_t offset,int whence); //若成功则返回新的文件偏移量,若出错则返回-1
#include <unistd.h>
ssize_t read(int filedes,void *buf,size_t nbytes);
#include <unistd.h>
ssize_t write(int filedes,const void *buf,size_t nbytes);
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
char buf[];
int n;
n = read(STDIN_FILENO, buf, );
if (n < ) {
perror("read STDIN_FILENO");
exit();
}
write(STDOUT_FILENO, buf, n);
return ;
}
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#define MSG_TRY "try again\n"
int main(void)
{
char buf[];
int fd, n;
fd = open("/dev/tty", O_RDONLY|O_NONBLOCK);
if(fd<) {
perror("open /dev/tty");
exit();
}
tryagain:
n = read(fd, buf, );
if (n < ) {
if (errno == EAGAIN) {
sleep();
write(STDOUT_FILENO, MSG_TRY, strlen(MSG_TRY));
goto tryagain;
}
perror("read /dev/tty");
exit();
}
write(STDOUT_FILENO, buf, n);
close(fd);
return ;
}
#include <unistd.h>
int dup(int filedes);
int dup2(int filedes,int filedes2);
//filedes2参数指定新描述符的数值。如果filedes2已经打开,则先关闭。
dup(filedes);等效于fcntl(filedes, F_DUPFD, 0);
dup2(filedes, filedes2);等效于
close(filedes2);
fcntl(filedes, F_DUPFD, filedes2);
区别
1).dup2是一个原子操作,而close及fcntl则包括两个函数调用,有可能在close和fcntl之间插入执行信号捕获函数
2).dup2和fcntl有某些不同errorno
9.sync,fsync ,fdatasync函数
为了解决延迟写的问题,保证磁盘上实际文件系统和缓冲区高速缓存中内容的一致性。
#include <unistd.h>
int fsync(int filedes); // 只对由文件描述符filedes指定的单一文件其作用,并且等待写磁盘操作结束
int fdatesync(int filedes); //功能和fsync差不多,但它还同步更新文件的属性
void sync(void); //将所有修改过的快缓冲区排入写队列,然后返回,它并不等待实际写磁盘操作结束
10.fcntl函数
可以改变已打开的文件性质
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
第三个参数总是一个整数,与上面所示函数原型中的注释部分相对应。但是在作为记录锁用时,第三个参数则是指向一个结构的指针。
fcntl函数有5种功能:
1).复制一个现有的描述符(cmd=F_DUPFD).
2).获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD).
3).获得/设置文件状态标记(cmd=F_GETFL或F_SETFL).
4).获得/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN).
5).获得/设置记录锁(cmd=F_GETLK,F_SETLK或F_SETLKW).
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#define MSG_TRY "try again\n"
int main(void)
{
char buf[];
int n;
int flags;
flags = fcntl(STDIN_FILENO, F_GETFL);
flags |= O_NONBLOCK;
if (fcntl(STDIN_FILENO, F_SETFL, flags) == -) {
perror("fcntl");
exit();
}
tryagain:
n = read(STDIN_FILENO, buf, );
if (n < ) {
if (errno == EAGAIN) {
sleep();
write(STDOUT_FILENO, MSG_TRY, strlen(MSG_TRY));
goto tryagain;
}
perror("read stdin");
exit();
}
write(STDOUT_FILENO, buf, n);
return ;
}
11.ioctl函数
ioctl用于向设备发控制和配置命令,有些命令也需要读写一些数据,但这些数据是不能用read/write读写的,称为Out-of-band数据。也就是说,read/write读写的数据是in-band数据,是I/O操作的主体,而ioctl命令传送的是控制信息,其中的数据是辅助的数据。例如,在串口线上收发数据通过read/write操作,而串口的波特率、校验位、停止位通过ioctl设置,A/D转换的结果通过read读取,而A/D转换的精度和工作频率通过ioctl设置。
#include <unistd.h> /*System V*/
#include <sys/ioctl.h> /*BSD and Linux*/
#include <stropts.h> /*XSI STREAMS*/
int ioctl(int filedes, int request, . . .);
以下程序使用TIOCGWINSZ命令获得终端设备的窗口大小。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
int main(void)
{
struct winsize size;
if (isatty(STDOUT_FILENO) == )
exit();
if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &size)<) {
perror("ioctl TIOCGWINSZ error");
exit();
}
printf("%d rows, %d columns\n", size.ws_row, size.ws_col);
return ;
}
12./dev/fd
比较新的unix/linux系统都提供名为/dev/fd的目录,其中有文件0、1、2等文件,打开这些文件,相当于复制这些文件描述符
fd=open("/dev/fd/0",mode);
等价于
fd=dup(0);
文件描述符fd和0将共享一个文件表记录项。
13.文件共享
文件共享是指不同进程间打开文件的共享。内核通过三种数据结构来表示打开的文件,
1).每个进程有个进程表项,表中是打开文件的描述符向量。每个向量包含了文件描述符标记和一个指向文件表项的指针;
2).内核为所有打开的文件维护一个文件表,每个文件表项包括了a,文件状态标记,如读、写、添加、非阻塞等b,当前的文件偏移量c,指向文件v-node表项的指针;
3).每个打开文件或设备都有一个v-node结构 ,包含文件类型和指向操作文件的函数的指针。
当两个以上独立进程打开同一个文件实现文件共享时,内核维护不同的文件表项,就是两个以上进程表项中的文件表项指针指向不同的文件表项,而不同的文件表项中的v-node指针指向同一个v-node而实现文件共享。由于每个进程有自己的打开文件表项,所以有自己的文件打开状态以及文件偏移量。
需要注意的是Linux没有将相关数据分为i节点和v节点,而是采用了一个独立于文件系统的i节点(通用i-node结构)和一个依赖于文件系统的i节点


系统编程--文件IO的更多相关文章
- linux系统编程--文件IO
系统调用 什么是系统调用: 由操作系统实现并提供给外部应用程序的编程接口.(Application Programming Interface,API).是应用程序同系统之间数据交互的桥梁. C标准函 ...
- Linux系统编程--文件IO操作
Linux思想即,Linux系统下一切皆文件. 一.对文件操作的几个函数 1.打开文件open函数 int open(const char *path, int oflags); int open(c ...
- Linux系统编程@终端IO
Linux系统中终端设备种类 终端是一种字符型设备,有多种类型,通常使用tty 来简称各种类型的终端设备.终端特殊设备文件一般有以下几种: 串行端口终端(/dev/ttySn ) ,伪终端(/dev ...
- Linux系统编程@文件操作(一)
只总结了部分常用的内容,详细内容参考<UNIX环境高级编程>及相关书籍. Linux中文件编程可以使用两种方法 Linux系统调用(依赖于系统) C语言库函数(不依赖于系统) Linux系 ...
- linux系统编程:IO读写过程的原子性操作实验
所谓原子性操作指的是:内核保证某系统调用中的所有步骤(操作)作为独立操作而一次性加以执行,其间不会被其他进程或线程所中断. 举个通俗点的例子:你和女朋友OOXX的时候,突然来了个电话,势必会打断你们高 ...
- Linux系统编程--文件描述符的复制dup()和dup2()【转】
本文转载自:http://blog.csdn.net/tennysonsky/article/details/45870459 dup() 和 dup2() 是两个非常有用的系统调用,都是用来复制一个 ...
- 系统编程--标准IO
1.流和FILE对象 对于国际字符集,一个字符可以由一个以上的字节来表示.标准I/O文件流可以用来操作单字节和多字节(宽,wide)字符集.一个流的方向(orientation)决定了字符是以单字节还 ...
- 系统编程-文件IO-IO处理方式
IO处理五种模型 .
- 系统编程--高级IO
1.非阻塞I/O 非阻塞I/O使我们可以调用不会永远阻塞的I/O操作,例如open,read和write.如果这种操作不能完成,则立即出错返回,表示该操作如继续执行将继续阻塞下去.对于一个给定的描述符 ...
随机推荐
- Entity Framework 连接 mysql 。(code first模式)
准备工作 1.下载vs2015 2.下载mysql2017 3.安装 1.创建类库 . 2.打开Nuget包,下载最新版的entity framewor. 3.在引用中添加 mysql.data; m ...
- mingw libgcc_s_sjlj-1.dll is missing
习惯了在linux环境下工作,编译wingdows平台程序采用mingw工具.编译完,运行exe程序,弹出错误信息: libgcc_s_sjlj-1.dll is missing 百度了一下,原来是编 ...
- 移动页面请使用CSS3动画
说到动画,我们一般会使用jQuery 中的animate(); 在PC浏览器中,是很方便的,由于PC的高性能,这种不断修改DOM的做法确实不会出现太大的问题,但是在手机端就不同了. 手机上使用jQue ...
- JavaEE权限管理系统的搭建(一)--------项目中用到的知识点概括
转战Java有一段时间了,.net 已不再开发的新的工程,基本上在维护,最近大半年时间在学习Java,今天抽空将学习的到的知识,应用到了一个权限管理系统的小项目中,特此记录一下.代码如有不对之处,希望 ...
- java基础 序列化反序列化流 实现Serializable 接口 自动装载序列号到对象文本文件如修改不能反序列化对象文本,除非自定义long型常量 打印流
package com.swift.baseKnowledge; import java.io.File; import java.io.FileInputStream; import java.io ...
- JS底层挖掘
//Promise版本的Ajaxconst getJSON = function(url) { const promise =new Promise(function(resolve, reject) ...
- OCCI结果集(ResultSet)性能优化
对于ResultSet类中的next()方法,默认是一次检索一行数据,及一次检索执行一次网络往返,当结果集数量大时,效率低:对此OCCI提供了几种改善方法,即:在一次网络往返返回多行数据. 1. 通过 ...
- 出门旅行(tour)
出门旅行(tour) 题目描述: 在神奇的 oi 国度,有 n 个城市 m 条双向道路,每条道路连接了两个不同的城市.寒假到了,小 S 决定出门旅游一趟.因为以往跟团旅游多了,这次小 S 决定自驾游. ...
- lintcode_115_不同的路径 II
不同的路径 II 描述 笔记 数据 评测 "不同的路径" 的跟进问题: 现在考虑网格中有障碍物,那样将会有多少条不同的路径? 网格中的障碍和空位置分别用 1 和 0 来表示. ...
- springMVC集成logback日志系统
一.项目结构 项目介绍:maven搭建的web项目,实现Java日志记录功能.其中logback.xml为日志配置文件,spring-mvc-servlet.xml为spring controller ...