基于Linux的文件操作

Linux文件操作

Linux中,socket被认为是文件的一种,所以在数据传输过程中可以使用文件I/O函数

文件描述符

文件描述符是系统分配给文件或socket的整数

  • 0:标准输入
  • 1:标准输出
  • 2:标准错误

文件和套接字一般经过创建过程才会被分配文件描述符。但是上述3种输入输出对象即使未经过特殊的创建过程,程序开始运行后也会被自动分配文件描述符

文件描述符知识为了方便称呼操作系统创建的文件或socket所赋予的名字而已

文件访问操作

1.打开文件

int open(const char *path,int flag);
//第一个参数为文件路径,第二个为打开方式
//打开成功则返回文件描述符,失败则返回-1

打开方式有:image

第二个参数如果要传递多个参数则用|分隔

2.关闭文件

#include<unistd.h>
int close(int fd);
成功返回0,失败返回-1
    fd为待关闭的socket,或文件
    close系统调用并非总是立即关闭一个连接,而是将fd的引用计数减1,当fd引用计数为0则真正关闭连接
    多进程中一次fork系统调用默认将父进程中打开的socket引用计数+1,因此必须在父子进程中都对该socket执行close才能将连接关闭

3.写文件

#include<unistd.h>
ssize_t write(int fd,const void* buf,size_t nbytes);
成功返回写入的字节数,失败返回-1
    fd,文件描述符
    buf为保存要传输数据的缓冲地址值
    nbytes:要传输数据的字节数

image

#include<stdlib.h>
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
void error_handling(char *message){
    fputs(message,stderr);
    fputc('\n',stderr);
    exit(1);
}
int main(){
    int fd;
    char buf[] = "let's go!\n";
    fd = open("data.txt",O_CREAT|O_WRONLY|O_TRUNC);
    if(fd==-1){
        error_handling("open() error");
    }
    printf("文件描述符:%d\n",fd);
    if(write(fd,buf,sizeof(buf))==-1){
        error_handling("write() error");
    }
    close(fd);

    return 0;
}
root@ziggy-virtual-machine:~/socktest/file_operate# ls
openfile  openfile.cpp
root@ziggy-virtual-machine:~/socktest/file_operate# ./openfile 
文件描述符:3
root@ziggy-virtual-machine:~/socktest/file_operate# ls
data.txt  openfile  openfile.cpp
root@ziggy-virtual-machine:~/socktest/file_operate# cat data.txt 
let's go!
root@ziggy-virtual-machine:~/socktest/file_operate# 

4.读取文件

image

//通过read()函数读取文件中的数据
#include<unistd.h>
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<fcntl.h>
using namespace std;

void error_handling(char *message){
    fputs(message,stderr);
    fputc('\n',stderr);
    exit(1);
}

#define BUF_SIZE 100
int main(){

    int fd;//打开的文件的文件描述符
    char buf[BUF_SIZE];
    fd = open("data.txt",O_RDONLY);//只读
    if(fd==-1){
        error_handling("open() error");
    }


    cout<<sizeof(buf)<<endl;//输出为100
    printf("文件描述符:%d\n",fd);

    if(read(fd,buf,sizeof(buf))==-1){
        error_handling("read() error");
    }
    printf("file data:%s\n",buf);

    close(fd);
    return 0;
}

测试文件描述符

#include<unistd.h>
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<fcntl.h>
#include<sys/socket.h>

using namespace std;

int main(){


//创建socket文件描述符和打开文件open函数返回的文件描述符,对比发现规律

    int fd1,fd2,fd3;
    fd1 = socket(PF_INET,SOCK_STREAM,0);
    fd2 = open("test.dat",O_CREAT|O_WRONLY|O_TRUNC);
    fd3 = socket(PF_INET,SOCK_DGRAM,0);
    printf("file des 1: %d\n",fd1);
    printf("file des 1: %d\n",fd2);
    printf("file des 1: %d\n",fd3);
    close(fd1);
    close(fd2);
    close(fd3);
    return 0;
}

image
文件描述符从3开始编号,0,1,2都分配给了标准I/O

posted @ 2021-09-06 15:42  ziggystardust  阅读(43)  评论(0)    收藏  举报