1.2 基于Linux的文件操作
对于Linux
而言,socket
操作与文件操作没有区别,因此可用文件IO。在Windows
中socket
则需要特殊的数据传输相关函数。
底层文件访问和文件描述符
底层的意思是 与标准无关的操作系统提供的。即,由Linux
提供,而非标准C。
文件描述符 | 对象 |
---|---|
0 | 标准输入:Standard Input |
1 | 标准输出:Standard Output |
2 | 标准错误:Standard Error |
文件和套接字一般经过创建过程才会被分配文件描述符。上方三种,即使未经过特殊的创建,程序开始运行后也会被自动分配文件描述符。
文件描述符只是OS描述文件的数而已。我们只要告诉操作系统 100 ,OS就知道是哪个文件。
打开文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *path, int flag);
//成功返回文件描述符,否则返回-1
path
是目标文件名和路径信息,flag
是文件打开模式。
打开模式 | 含义 |
---|---|
O_CREAT | 必要时创建文件 |
O_TRUNC | 删除全部现有数据 |
O_APPEND | 维持现有数据,保存新数据到现有数据后面 |
O_RDONLY | 只读 |
O_WRONLY | 只写 |
O_RDWR | 读写 |
如果使用多个模式,需要使用or
连接,在c
中是|
。
关闭文件
使用文件必须关闭。
#include <unistd.h>
int close(int fd);
//成功返回0,否则-1;
传入文件描述符,Linux
中还可以关闭套接字,因为套接字就是文件,Linux
中一切皆文件!
写入文件
Linux
不区分文件和套接字,因此可以通过write
传输。
#include <unistd.h>
ssize_t write (int __fd, const void *__buf, size_t __nbytes);
//成功返回写入字节数,否则-1;
三个参数分别是 文件描述符,保存要传输数据的缓冲地址值,要传输数据的字节数。
对于size_t
的补充,size_t
是通过typedef
声明的unsigned int
类型,ssize_t
前面多的s
则代表着signed
,因此是signed int
。
这些类型是元数据类型(primitive
),在sys/types.h
声明,因为原先主流操作系统的int
是16位,而如今是32位,因此使用size_t
等,可以在修改数据类型时候,减少代码变动。只需要修改typedef
声明即可。又因为要与程序员定义的数据类型进行区分所以在末尾加上_t
。
读取文件
#include <unistd.h>
ssize_t read(int fd, void * buf, size_t nbytes);
//成功则返回接受的字节数(遇到文件结尾则返回0),否则-1
三个参数分别是 文件描述符,保存要接受数据的缓冲地址值,要接受数据的字节数