菜鸟笔记
提升您的技术认知

系统调用——open、write、read和close

一、文件描述符
每一个进程都有一个与之相关的文件描述符,它们是一些小值整数,我们可以通过这些文件描述符来访问打开的文件。
一般地,一个程序开始运行时,会自动打开3个文件描述符:
0——–标准输入———-stdin
1——–标准输出———-stdout
2——–标准错误———-stderr

二、write系统调用

1.write系统调用的原型:

#include <unistd.h>

size_t write(int flides, const void *buf, size_t nbytes);

write系统调用,是把缓存区buf中的前nbytes字节写入到与文件描述符flides有关的文件中,write系统调用返回的是实际写入到文件中的字节数

2.举例,将一串字符写入到标准输入、输出里

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    int real_num = write(1,"here is my word\t",17);
    if(real_num!=16)//没有错误,只是为了方便查看写成16
    {
        write(1,some error);
        //write(0,some error)
        //如果写入到标准输入里,程序结束时会自动将标准输入里的内容输出
    }

     exit(0);
}

在Linux上的执行结果:

三、read系统调用

read系统调用的原型:

#include <unistd.h>

size_t read(int flides, void *buf, size_t nbytes);

read系统调用,是从与文件描述符flides相关联的文件中读取前nbytes字节的内容,并且写入到数据区buf中。read系统调用返回的是实际读入的字节数

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    char buf[128] = {
  0};
    int real_num;

    real_num = read(0,buf,128);
    if(real_num==-1)//读取失败
    {
        write(2,"a error happened\n",17);
    }
    else
    {
        write(1,"succuss",7);
    }

    exit(0);
}

运行结果:

四、open系统调用
在上面的write和read中,我们使用的文件描述符是自程序运行就有了的3个文件描述符,那么接下来open就可以创建新的文件描述符,供write和read来使用。

open系统调用的原型:

#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

int main()
{
    int open(const *path, int oflags);//1
    int open(const *path, int oflags, mode_t mode);//2

    exit(0);
}

open有两种调用方法:

1.

int open(const *path, int oflags);

将准备打开的文件或是设备的名字作为参数path传给函数,oflags用来指定文件访问模式。open系统调用成功返回一个新的文件描述符,失败返回-1。
其中,oflags是由必需文件访问模式和可选模式一起构成的(通过按位或“|”):
必需部分:
O_RDONLY———-以只读方式打开
O_WRONLY———以只写方式打开
O_RDWR————以读写方式打开
可选部分:
O_CREAT————按照参数mode给出的访问模式创建文件
O_EXCL————–与O_CREAT一起使用,确保创建出文件,避免两个程序同时创建同一个文件,如文件存在则open调用失败
O_APPEND———-把写入数据追加在文件的末尾
O_TRUNC———–把文件长度设置为0,丢弃原有内容

将一个现有文件的内容拷贝到新文件中,新文件已存在

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    char buff[128] = {
  0};
    int out = open("file.c",O_RDONLY);//以只读方式打开文件
    int in = open("text.c",O_WRONLY);//以只写方式打开另外一个文件

    int real_num_read = read(out, buff, 128);
    while(real_num_read)//读到即写入
    {
        write(in, buff, 128);//写入的字节数为实际读到的个数
    }

    close(out);
    close(in);
    exit(0);
}

2.

int open(const *path, int oflags, mode_t mode);

在第一种调用方式上,加上了第三个参数mode,主要是搭配O_CREAT使用,同样地,这个参数规定了属主、同组和其他人对文件的文件操作权限。

S_IRUSR———-读权限 )
S_IWUSR———写权限 ——文件属主
S_IXUSR———-执行权限 )
S_IRGRP———-读权限 )
S_IWGRP———写权限 ——文件所属组
S_IXGRP———-执行权限 )
S_IROTH———-读权限 )
S_IWOTH———写权限——其他人
S_IXOTH———-执行权限 )
另外,也可以用文字设定法:
0——————无权限
1——————只执行
2——————只写
4——————只读

将一个现有文件的内容拷贝到新文件中,新文件需自行创建

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

int main()
{
    int fr = open("./text_open_file.txt", O_RDONLY);
    assert(fr!=-1);
    int real_num;
    char buf[128] = {
  0};
    real_num = read(fr,buff,127);

    int fw = open("./file.txt",O_WRONLY | O_CREAT, 0600);
    assert(fw!=-1);

    while(real_num)
    {
        write(fw,buff,127);
        real_num = read(fr,buff,127);
    }

    close(fw);
    close(fr);
    exit(0);
}

两个文件的内容:

五、close系统调用
终止文件描述符flides与其对应的文件间的联系,文件描述符被释放,可重新使用。

1.close系统调用

#include <unistd.h>

int close(int flides);

使用完文件描述符之后,要记得释放!