本文主要介绍一下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_systemwu@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提高了不少