AUP学习笔记--基本的I/O系统调用
来源:互联网 发布:surface rt安装linux 编辑:程序博客网 时间:2024/06/13 03:05
最近在读高级unix编程一书,没事就写写总结吧,把一些重点内容记录下来,以后要复习或者找资料的话还可以省点时间,闲话不多说,unix下系统编程我想跟Linux下的应该没什么区别,一般说来我会直接在linux下进行实验,说到这里,前些天把自己的本整成了双系统,分了六十G给fedora16,使用GNOME3感觉很清爽,界面也很炫,一些工作上用到的toolchain也配置好了,还以为有多么复杂,没想到只需要改个路径就可以~!这章的内容应该是在十天前看的,主要内容也就是几个系统调用函数的使用,包括open/creat/close/read/write/lseek/umask/unlink,这些应该是用的比较多的了,其他的比如pread/pwrite/readv/writev这几个好像见得不多,没有太细看,大概知道是干嘛的,下面具体说说这几个函数的用法:
1.open
#include <sys/stat.h>#include <fcntl.h>/* Return fd or -1 on error,set errno */int open(const char *path, /* file path name */ int flags, /* open flags */mode_t perms /* permissions(when creating) */);可以用open来打开一个已经存在的文件(普通文件、特殊文件或命名管道)或者创建一个新的文件,但只能创建普通文件。文件一旦打开的话,open以及相关的read、write、lseek、close调用就可以使用返回的文件描述符。
flags的取值:
O_RDONLY 以只读方式打开文件,O_WRONLY 以只写方式打开文件,O_RDWR 以可读写方式打开文件
对于一个已经存在的文件,参数perms是没有用的,通常省略,文件偏移量(读写用到的)位于文件的第一个字节,比如打开一个存在的文件:
int fd;fd = open("/home/rudyn/tmpfile", O_RDONLY);
用open创建一个新的文件,需要在flags中加入标志O_CREATE,当然还要结合O_WRONLY或者O_RDWR一起用,不然的话创建的文件就是个只读的,意义不大,这个时候perms参数就要用得上了:
fd = open("/home/rudyn/tmpfile", O_RDWR | O_CREATE, PERM_FILE);如果需要创建一个新的、没有任何内容的文件,或者说该文件存在,但是要将其数据清涂并置文件偏移量为0,那么flag:O_TRUNC可以实现这种功能。因此可以在上句中加入这个标志,不过O_TRUNC会破坏文件的数据,因此只要相应的进程具有写的权限,那么它就可以清除文件的内容,也就是对O_RDONLY的文件不起任何作用。
2.creat
#include <sys/stat.h>#include <fcntl.h>int creat(const char *file_path, /* path name */mode_t perms /* permissions */);/* return fd or -l on error */实际上,creat只是一个宏定义:
#define creat(path, perms) open(path, O_WRONLY|O_CREAT|O_TRUNC, perms)标志:O_EXCL,如果它和O_CREAT标记一起使用,文件若存在,则创建文件操作失败,如果没有用O_CREAT,open的操作是文件存在则打开,文件不存在则失败,而和O_EXCL|O_CREAT这个标志用的时候,open的结果将会是:文件不存在,则创建否则失败。
这章中还讲到了用文件当锁的内容,通过O_EXCL这个标志来实现,判断文件的存在性来控制进程的状态,虽然书中也说效率低,但是也是一种思想!
3.unlink
#include <unistd.h>/* Return 0 on success or -1 on error */int unlink( const char *path; /* path name */);unlink能从目录中删除链接,并将信息节点所引用的文件链接数减一,如果链接数减到零,文件系统将删除这个文件它所占用的磁盘空间可再次被利用,信息节点也可被重用。它可以解除任何类型的文件,但是只有超级用户才可以解链目录,不过解链目录还是应该用rmdir()。
4.umask
#include <sys/stat.h>mode_t umask(mode_t mask; /* new mask value */);/* Return previous mask */linux中新创建的文件都有个默认的文件权限,它由九个位决定,比如某文件:-rwx-r-x-r-x,用数字表示为755,那么系统的默认umask值(对于文件来说)就是:022,umask是为了设置和得到文件模式的创建掩码,umask不会返回error,它总返回之前的值。
5.mkstemp和tmpfile
这两件函数是标准C中的内容,不再说了,回头翻下C标准库就行,它们用于创建一个临时的文件。
6.文件偏移量以及标志O_APPEND
文件打开的时候,如果没有偏移标志指定,其偏移量为零,读或写都会自动改变偏移量,文件偏移量是下一次读或写文件的位置,但是目录、套接字、命名管道和符号链接文件都没有文件偏移量。当文件以O_APPEND标志打开时,进行的读写操作都将通过隐含的lseek将文件偏移量设置在文件末尾,而不会覆盖前面的内容。
7.lseek
#include <unistd.h>off_t lseek(int fd, /* file descriptor */off_t pos, /* position */int whence /* interpretation */);/* Return new fd or -1 on error */参数whence取值:
SEEK_SET 将该文件偏移量设置到pos参数
SEEK_CUR 将该文件偏移量设置为其当前值加pos参数,pos可为正数,负数或0,0是查找当前文件偏移量
SEEK_END 将该文件偏移量设置为文件长度加pos参数,pos可为正数,负数或0,0是将文件偏移量设置为文件结尾
lseek最常用的三种方式:
(1).查找文件某个绝对位置
lseek(fd, offset, SEEK_SET);(2).查找文件末尾
lseek(fd, 0, SEEK_END);(3).查找文件偏移量当前位置
off_t cur_pos;cur_pos = lseek(fd, 0, SEEK_CUR);8.read
#include <unistd.h>ssize_t read(int fd, /* file descriptor */void *buf, /* buf for receiving data */size_t nbytes /* total to read */);read从fd描述的打开文件中读取nbytes数据至buf中。从当前文件偏移量开始读,完成读操作后,文件偏移量将增加所读字节数。返回值是所读字节数、文件结束标志0或者错误标志-1,读不受O_APPEND影响。如果需要读所有的数据,最好通过循环调用read,后面有个copy file的例子说明这一点。
9.write
#include <unistd.h>ssize_t write(int fd, /* file descriptor */const void *buf, /* data to write */size_t nbytes /* total to write */);/* Return number of bytes written or -1 on error */write将buf指缓冲区的nbytes字节写入fd所打开的文件中,写操作从文件偏移量当前位置开始,完成之后移动文件偏移量,若写入成功,返回已写的字节数,出错为-1。
10.close
#include <unistd.h>int close( int fd /* file descriptor */);/* return 0 on success or -1 on error */close没有做任何工作,仅仅使文件描述符可重用,删除打开的文件描述。
最后,附上两个文件读写的小程序,可以比较,帮助更好的理解系统调用:
File Copy A:
#define BUFSIZE 512void file_copy_a(char *src, char *dst){ int src_fd = -1, dst_fd = -1; ssize_t byte_read; char buf[BUFSIZE] = {0}; if (-1 == (src_fd = open(src, O_RDONLY))) { perror("File open error!\n"); goto end; } if (-1 == (dst_fd= open(dst, O_WRONLY | O_CREAT | O_TRUNC))) { perror("File create error!\n"); goto end; } while ((byte_read = read(src_fd, buf, sizeof(buf))) > 0) { if (write(dst_fd, buf, byte_read) != byte_read) { perror("write error!\n"); goto end; } } if (byte_read == -1) { perror("read error!\n"); goto end; } end: if(src_fd > 0) { close(src_fd); } if(dst_fd > 0) { close(dst_fd); }}
File Copy B:
#define BUFSIZE 512void file_copy_B(char *src, char *dst){ int src_fd = -1, dst_fd = -1; ssize_t byte_read, byte_write, n; char buf[BUFSIZE] = {0}; if (-1 == (src_fd = open(src, O_RDONLY))) { perror("File open error!\n"); goto end; } if (-1 == (dst_fd= open(dst, O_WRONLY | O_CREAT | O_TRUNC))) { perror("File create error!\n"); goto end; } while ((byte_read = read(src_fd, buf, sizeof(buf))) > 0) { byte_write = 0; do { if((n = write(dst_fd, &buf[byte_write], byte_read - byte_write)) < 0) { perror("write error!\n"); goto end; } byte_write += n; }while(byte_write < byte_read); } if (byte_read == -1) { perror("read error!\n"); goto end; } end: if(src_fd > 0) { close(src_fd); } if(dst_fd > 0) { close(dst_fd); }}
- AUP学习笔记--基本的I/O系统调用
- JAVA I/O系统学习笔记-部分
- Linux系统学习笔记:高级I/O
- Linux系统学习笔记:文件I/O
- Linux系统学习笔记:高级I/O
- 操作系统学习笔记:I/O输入系统
- 几个基本的I/O系统调用,你看你会了吗???
- Java I/O 学习笔记(2) 基本输入输出流
- Java I/O 学习笔记(3) 基本输入输出流过滤
- overlapped I/O的学习笔记
- linux 下基本的I/O系统函数
- JavaSE基础学习笔记-Java I/O 系统1
- JavaSE基础学习笔记-Java I/O系统2-File
- Java学习笔记—Java I/O系统(一)
- java学习笔记(9)-Java I/O系统
- I/O复用的系统调用select、poll、epoll
- I/O复用的系统调用——select
- 文件I/O编程学习笔记一(基于linux系统的文件编程)
- 百度网盘15G邀请码
- 我的一个网络层架构
- Linux内存点滴 用户进程内存空间
- poj 1011 小棍问题
- 深入理解计算机系统 chapter-1(笔记)
- AUP学习笔记--基本的I/O系统调用
- java 高新技术【11】 java 代理类
- set yii input form text field to read only.
- SSH 問題
- 今晚看到了传说中的方立勋老师
- poj 1020 分蛋糕问题
- android中的所有activity间动画跳转
- vc6.0 中dll文件的创建和使用
- 现在的问题