工学1号馆

home

linux底层文件访问

By Wu Yudong on October 21, 2016

本文主要介绍一下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

No comments yet.
To verify that you are human, please fill in "七"(required)