CSAPP(10)System-Level I/O

文章目录

  • Unix I/O
  • Opening and Closing Files
    • flags
    • mode
  • Reading and Writing Files
  • Robust Reading and Writing with the Rio Package
  • Reading File Metadata
  • Sharing Files
  • I/O Redirection
  • Standard I/O
  • Which IO Functions Should I Use

Unix I/O

当一个程序告诉内核它想open一个程序时,内核会返回一个descriptor(在避免重复后返回最小)。通过shell创建的进程默认打开了三个文件:standard input(descriptor 0),standard output(descriptor 1),standard error(descriptor 2)。可以使用里面的常量来表示 。
内核维护着一个file position来表示文件的偏移量,程序可以通过seek来设置
对于一个大小为 m m mbytes的文件,当从位置 k k k使用read操作读取nbytes的时候, k k k也会改变,当 k ≥ m k\geq m km的时候,会触发end-of-file,需要注意并不存在EOF这个字符

Opening and Closing Files

#include 
#include 
#include 

int open(char *filename,int flags,mode_t mode);
int close(int fd);

flags

其中flags可以有下列取值范围:

  • O_RDONLY
    reading only
  • O_WRONLY
    writing only
  • O_RDWR
    reading & writing
  • O_CREATE
    没有则创建
  • O_TRUNC
    文件存在则truncate
  • O_APPEND
    从末尾开始写
    上面的flag可以一起使用,例如
fd=Open("foo.text",O_WRONLY|O_APPEND,0);

mode

mode有以下取值范围

USR GRP(group) OTH(others)
R S_IRUSR S_IRGRP S_IROTH
W S_IWUSR S_IWGRP S_IWOTH
X S_IXUSR S_IXGRP S_IXOTH

可以配合umask来设置mode,如下所示

#define DEF_MODE S_IRUSR|IWUSR|IRGRP|S_IWGRP|S_IROTH|S_IWOTH
#define DEF_UMASK S_IWGRP|S_IWOTH
unmask(DEF_UMASK);
fd=Open("foo.txt",O_CREATE|O_TRUNC|O_WRONY,DEF_MODE);

Reading and Writing Files

#include 
//return number of bytes if ok,0 on EOF,-1 on error
ssize_t read(int fd,void *buf,size_t n);
//return number of bytes if ok,-1 on error
ssize_t write(int fd,const void *buf,size_t n);

Robust Reading and Writing with the Rio Package

Reading File Metadata

#include 
#include 
//return 0 if ok,-1 on error
int stat(const char *filename,struct stat *buf);
int fstat(int fd,struct stat *buf);

上面两个函数的差别就是第一个入参使用了文件名或者descriptor。至于struct stat结构如下

struct stat{
	dev_t			st_dev;//divice
	ino_t			st_ino;//inode
	mode_t			st_mode;//protection and file type
	nlink_t			st_nlink;//number of hard links
	uid_t			st_uid;//owner user id
	gid_t			st_gid;//owner group id
	dev_t			st_rdev;//device type if inode
	off_t			st_size;//total size in bytes
	unsigned long	st_blksize;//blocksize
	unsigned long	st_blocks;//number of blocks allocated
	time_t			st_atime;//time of last access
	time_t 			st_mtime;//time of last modification
	time_t			st_ctime;//time of last change
};

Sharing Files

文件的共享涉及到三张表descriptor tablefile tablev-node table,其中后两张表有可能多个进程共享,对于第二张表的共享如下图所示.此时需要注意父子进程对文件的读写会相互影响。

I/O Redirection

#include 
int dup2(int oldfd,int newfd);

IO重定向使用上面方法,其本质如下图所示(拷贝了descriptor table的值)

Standard I/O

ANSI C在Unix I/O的基础上提供了一些更高级的IO函数,被称为standard I/O library。同样默认有三个File

#include 
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;

Which IO Functions Should I Use

这里提到了文件IO和网络IO的差别,最终建议时文件io可以使用标准库,而网络io不要这样做。

你可能感兴趣的:(底层知识)