基于Linux的文件操作
Linux文件操作
Linux中,socket被认为是文件的一种,所以在数据传输过程中可以使用文件I/O函数
文件描述符
文件描述符是系统分配给文件或socket的整数
- 0:标准输入
- 1:标准输出
- 2:标准错误
文件和套接字一般经过创建过程才会被分配文件描述符。但是上述3种输入输出对象即使未经过特殊的创建过程,程序开始运行后也会被自动分配文件描述符
文件描述符知识为了方便称呼操作系统创建的文件或socket所赋予的名字而已
文件访问操作
1.打开文件
int open(const char *path,int flag);
//第一个参数为文件路径,第二个为打开方式
//打开成功则返回文件描述符,失败则返回-1
打开方式有:
第二个参数如果要传递多个参数则用|分隔
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:要传输数据的字节数

#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.读取文件

//通过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;
}

文件描述符从3开始编号,0,1,2都分配给了标准I/O
学习的时候喜欢用Markdown做记录,存货已经堆满文件夹了

浙公网安备 33010602011771号