linux文件系统
linux由虚拟文件系统VFS提供同一套API操作不同的文件类型。
- 普通文件:存储设备上的文件,如C文件、目录、可执行文件等
- 字符设备文件:可以像文件一样访问的设备,如串口、控制台
- 块设备文件:需通过内存缓冲区且一次读写访问固定大小数据的设备,不直接对设备进行数据读写。如磁盘、软盘、光驱等
- socket文件:通过文件描述符抽象实现对网络的访问
创建文件系统
查看分区情况
fdisk -l
建立分区(假设目标磁盘为dev/sdb)
fdisk /dev/sdb
之后根据提示输入对应命令字操作
- a 设置为启动分区
- b 编辑bsd磁盘
- c 设置兼容dos标志
- d 删除一个分区
- l 列出当前系统支持的分区方式
- m 打印命令/help
- n 增加一个分区
- o 建立新的dos分区表
- p 打印分区情况
- q 不保存退出
- s 建立一个新的Sun空磁盘
- t 改变分区ID
- u 改变显示单元
- v 修正分区表
- w 保存并退出
- x 专家模式
格式化分区
mkfs.ext3 /dev/sdb1 //将dev/sdb1格式化为ext3类型文件系统
挂载分区
mount /dev/sdb1 /test //将/dev/sdb1 挂载到/test
mount命令用于挂载文件,其使用格式如下:
mount -t type mountpoint device -o options
上面的命令表示将文件类型为type的设备device按照options设置挂载到mountpoint上
查看分区挂载情况
df
文件操作
文件描述符(file descriptor)
linux通过一个整型数字文件描述符来表示文件,是一个与系统设置有关的有限资源,使用完毕后必修及时释放,其值仅在同一进程有效;
系统已分配3个文件描述符
- 0->标准输入(stdin)
- 1->标准输出(stdout)
- 2->标准错误(stderr)
打开/创建文件
//open()函数
int open(const char *pathname,int flags);
int open(const char *pathname,int flags,mode_t mode);
- 使用时需包含头文件sys/types.h、sys/stat.h、fcntl.h
- 成功返回文件描述符,失败返回-1
- pathname最大长度通常为1024,不同系统有差别,超长自动截断
- flags
- O_RDONLY 0 只读
- O_WRONLY 1 只写
- O_RDWR 2 可读可写
- O_APPEND 写操作时追加
- O_CREAT 不存在则创建,此时需设置mode参数以确定新文件权限
- O_EXCL 查看文件是否存在,存在时返回错误
- O_TRUNC 将文件长度截断为0,若文件存在并成功打开,则文件长度截断为0
- O_NONBLOCK 以非阻塞方式打开文件,不指定是默认阻塞方式打开
- mode参数值与含义
选项 | 值 | 含义 |
---|---|---|
S_IRWXU | 00700 | 用户(文件所有者)有读写和执行权限 |
S_IRUSR | 00400 | 用户有读权限 |
S_IWUSR | 00200 | 用户有写权限 |
S_IXUSR | 00100 | 用户有执行权限 |
S_IRWXG | 00070 | 组用户(文件所有者)有读写和执行权限 |
S_IRGRP | 00040 | 组用户有读权限 |
S_IWGRP | 00020 | 组用户有写权限 |
S_IXGRP | 00010 | 组用户有执行权限 |
S_IRWXO | 00007 | 其他用户(文件所有者)有读写和执行权限 |
S_IROTH | 00004 | 其他用户有读权限 |
S_IWOTH | 00002 | 其他用户有写权限 |
S_IXOTH | 00001 | 其他用户有执行权限 |
打开文件,不存在是创建文件并打开:
int fd=-1;
char filename[]="test.txt";
fd=open(filename,O_RDWR|O_CREAT|O_EXCL,S_IRWXU);
if(fd==-1){
fd=open(filename,O_RDWR);
}
creat()函数
int creat(const char *pathname,mode_t mode)
creat函数相当于open函数的缩写版本,等效于:
int open(pathname,O_WRONLY|O_CREAT|O_TRUNC,mode)
关闭文件
close()函数
int close(int fd);
- 关闭一个文件描述符,使改描述符可以再次使用并释放文件占用的资源
- 成功返回0,失败返回-1,通常不检查返回值
- 头文件为 unistd.h
读取文件
read()函数
从文件描述符fd对应的文件读取count字节数据放入buf开始的缓冲区
ssize_t read(int fd,void * buf,size_t count);
- 头文件 unistd.h
- count为0则返回0,count大于SSIZE_MAX则结果不可预料
- 读取成功时,读取位置指针向后移动读取成功的字节数
- 函数执行成功,返回读取的字节数,出错返回-1,达到文件末尾返回0
- 读取数据时,需要根据返回实际读取的数据大小来进行处理,而不能按照count来处理
- 读取普通文件时,若剩余字节数小于count,则返回剩余字节数
- 从中断设备/网络读取数据时,通常能够读取的数据小于请求大小
写文件
write()函数
向文件描述符fd对应的文件写入count字节数据,buf为数据开始的缓冲区
ssize_t write(int fd,void * buf,size_t count);
- 头文件 unistd.h
- 成功返回写入数据字节数,失败返回-1
- write函数不能保证将数据成功写入磁盘等块设备(只是写入缓冲区,等待系统处理)
文件偏移
lseek()函数
off_t lseek(int fd,off_t offset,int whence)
- 头文件sys/types.h unistd.h
- 按照操作模式whence和便宜大小offset重设文件偏移量
- 成功返回新的文件偏移量,失败返回-1;文件偏移量可以为负值
- whence
- SEEK_SET 文件偏移量距离文件起始处offset字节
- SEEK_CUR 文件偏移量为当前值加上offset
- SEEK_END 文件偏移量为文件长度加offset
//获取当前偏移量,如果参数 fd(文件描述符)指定的是 pipe(管道)、FIFO 或者 socket,lseek 返回 -1 并且置 errno 为ESPIPE。
off_t cur=lseek(fd,0,SEEK_CUR)
//获取文件长度
cur=lseek(fd,0,SEEK_END)
//将偏移量移至文件开头
cur=lseek(fd,0,SEEK_SET)