本文主要介绍一下linux底层文件访问的系统调用
本文地址:http://wuyudong.com/2016/10/21/2862.html,转载请注明出处。
1、write系统调用
作用是把缓冲区buf的前nbytes个字节写入与文件描述符fildes(0:表示标准输入,1:表示标准输出,2:表示标准错误)关联的文件中,函数返回0表示没有写入任何数据,如果返回-1表示write调用的过程中出错,错误代码保存在全局标量errno中,函数原型如下:
#include <unistd.h> size_t write(int fildes, const void *buf, size_t nbytes);
写一个简单的程序:
#include<stdio.h> #include<unistd.h> int main() { if((write(1, "Here is some data\n", 18) != 18)) write(2, "A write error has occurred on file descripter 1\n", 46); return 0; }
2、read系统调用
作用是从文件描述符fildes相关联的文件里读入nbytes个字节的数据,并把它们放在数据区buf中,返回实际读入的字节数,可能小于请求的字节数。函数返回0表示没有读入任何数据,如果返回-1表示read调用的过程中出错,函数原型如下:
#include <unistd.h> size_t read(int fildes, void *buf, size_t nbytes);
下面写一个简单的程序
#include<stdio.h> #include<unistd.h> int main() { char buf[128]; int nread; nread = read(0, buf, 128); if(nread == -1) write(2, "A read error has error has occurred\n", 26); if(write(1, buf, nread) != nread) write(2, "A write error has occurred\n", 27); return 0; }
wu@ubuntu:~/opt/Cproject$ echo hello here | ./test
hello here
3、open系统调用
为了创建一个新的文件描述符,你需要使用open系统调用
#include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> int open(const char *path, int oflags); int open(const char *path, int oflags, mode_t mode);
4、close系统调用
使用close调用终止文件描述符fildes与其对应的文件之间关联,调用成功返回0,出错时返回-1
#include <unistd.h> int close(int fildes);
5、ioctl系统调用
ioctl系统调用很杂。提供了一个用于控制设备及其描述符行为和配置底层服务的接口,具体可参见手册
#include <unistd.h> int ioctl(int fildes, int cmd, ...);
接下来实践一下
实验1:一个文件的复制程序
#include<unistd.h> #include<sys/stat.h> #include<fcntl.h> #include<stdlib.h> int main() { char c; int in, out; in = open("file.in", O_RDONLY); out = open("file.out", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); while(read(in, &c, 1) == 1) write(out, &c, 1); return 0; }
运行程序:
wu@ubuntu:~/linuxc/chapter03$ gcc copy_system.c -o copy_system wu@ubuntu:~/linuxc/chapter03$ TIMEFORMAT="" time ./copy_system 0.09user 2.75system 0:02.94elapsed 96%CPU…… wu@ubuntu:~/linuxc/chapter03$ ls -ls file.in file.out 1024 -rwxrw-rw- 1 wu wu 1048576 Apr 12 2007 file.in 1024 -rw------- 1 wu wu 1048576 Oct 21 04:38 file.out
file.in大小为1MB的文件,可以看到整个赋值过程只需要不到3s就可以完成
实验2:另一个文件的复制程序
可以改进上面的复制策略,通过复制大一些的数据块来改善效率低的问题,每次复制1k的数据块
#include<fcntl.h> #include<stdlib.h> int main() { char block[1024]; int in, out, nread; in = open("file.in", O_RDONLY); out = open("file.out", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); while(nread = read(in, block, sizeof(block)) > 0) write(out, block, nread); return 0; }
运行程序:
wu@ubuntu:~/linuxc/chapter03$ gcc copy_block.c -o copy_block
wu@ubuntu:~/linuxc/chapter03$ rm file.out
wu@ubuntu:~/linuxc/chapter03$ TIMEFORMAT=”” time ./copy_block
0.00user 0.00system 0:00.00elapsed 66%CPU……
可以看到程序的执行时间为0s,说明瞬间就搞定,相比之前的3s提高了不少
Comments