1、文件描述符
在linux中,文件描述符一共哟与1024个(0 ~ 1023)
0:STDIN_FILENO 标准输入 键盘
1:STDIN_FILENO 标准输出 屏慕
2:STRERR_FILENO 标准错误
说明:1、前面三个值012由系统占用,用户不能获取
2、文件描述符的次数优先,所以每次打开一个用完之后需要关闭它
3、文件描述符的值是从3开始
4、如果删除了某一个文件描述符的值,下次打开文件优先重复利用被删除的值
5、不能重复关闭同一个文件描述符,会报错
测试代码:
当前目录下面有1.txt 2.txt 3.txt
fd1 = open("1.txt",O_RDWR) //fd1=3
fd2 = open("2.txt") //fd2=4
fd3 = open("3.txt") //fd3=5
close(fd1);
fd4 = open("1.txt") //fd4=3
fd5 = open("2.txt") //fd5=6
close(fd2);
close(fd3);
fd6 = open("2.txt") //fd6=4
fd7 = open("2.txt") //fd7=5
2、open函数
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char* pathname,int flags);
int open(const char* pathname,int flags.mode_t mode);
参数说明:
pathname:文件路径名字
flag:标志量(访问权限)
O_RDONLY:只读
O_WRONLY:只写
O_RDWR:可读可写
O_CREAT:如果没有则自动创建
--->如果flags中有O_CREAT,那么需要填写mode这个参数
--->如果flags中没有O_CREAR,那么mode这个参数填了也没用
O_TRUNC:如果文件存在并且是一个普通文件,而且打开方式是O_WRONLY|O_TRUNC,
那么这个文件就会被清空
O_APPEND:以追加的方式打开文件,在每一次写之前,文件的定位在末尾
O_EXCL:跟上面的创建配套使用,如果文件存在了则打开失败
O_DIRECTORY:判断文件是否是目录,如果不是则打开失败
返回值:成功:文件描述符
失败:-1
说明:1、使用带mode参数的read的时候,如果需要检验设置的权限,需要到家目录里执行
(不要在共享文件夹里面执行,因为共享文件夹的权限和linux权限有冲突)
2、创建文件的权限最终由mode和umask(文件权限掩码)共同决定
3、mode必须要接合O_CREAT使用给才能由i笑熬过(使用或(|)使用多个参数)
3、close函数
#include <unistd.h>
int close(int fd);
参数说明:
fd::文件描述符
返回值:成功:0
失败:-1
说明:如果重复关闭同一个文件,也会出错
系统的打印如下:close fd fail:Bad file descriptor
4、write函数
#include <unistd.h>
ssize_t write(int fd,const void* buf,size_t count);
参数说明:
fd:文件描述符
buf:存储你要写出去的字节的buffer
count:你想要写入的字节数
返回值:成功:返回你实际写入的字节数(如果返回值是0,表示没有有说明可以写入)
失败:-1
说明:char buf[1024] = "abcdefg"
ret = write(fd,buf,15);
实际返回15个字节不是7个字节,超过有效字节则自动补0
5、read函数
#include <unistd.h>
ssizde_t read(int fd,void* buf,size_t count);
参数说明:fd:文件描述符
buf:存储你读取字节的buffer
count:你想要读取的字节数
返回值:成功:返回取得有效字节数(如果返回值是0,表示读取到了文件尾)
失败::-1
说明:1、在windows手动输入字符的时候,最后的换行符也是字节
可以通过软件(notepad)来查看(视图-》显示符号-》显示行尾符)
2、定义的时候需要对buf初始化,三种方法
//char buf[1024] = { 0 };
//bzero(buf,sizeof(buf));
//memset(buf,0,sizeof(buf));
6、lseek函数
//类似鼠标移动光标的作用
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd,off_t offset,int whence);
参数说明:
fd:文件描述符
offset:偏移量
whence:基准坐标
SEEK_SET(文件头):The offset is set to offset bytes.
SEEK_CUR(当前位置):The offset is set to its current location plus offset bytes.
SEEK_END(文件尾):The offset is set to the size of the file plus offset bytes.
返回值:成功:返回实际偏移量(当前光标距离文件头的距离)
失败:-1
说明:1、可以利用SEEK_END计算文件大小(size = lseek(fd,0,SEEK_END));
2、光标随着读写一直在移动(在非人为干预lseek的情况下)
7、测试代码
#include <sys/stat.h>
#include <fcntl.h>
/*close read write*/
#include <unistd.h>
int main(int argc,char **argv)
{
//打开文件
int fd;
fd = open("1.txt",O_RDWR|O_CREAT); //手动创建
if(fd < 0)
{
perror("open file fail");
return -1;
}
//写文件
int ret=0; //用来接收写的返回值
char buf[]="abc";
ret = write(fd,buf,20);
printf("buf:%s ret:%d\n",buf,ret);
//关闭文件
close(fd);
return 0;
}
#include <stdio.h>
/*open*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/*close*/
#include <unistd.h>
int main(int argc,char **argv)
{
int ret = 0; //用来接收返回值
//打开文件
int fd;
fd = open("1.txt",O_RDWR); //手动创建1.txt文件
if(fd < 0) //判断条件一定要写
{
perror("open file fail"); //系统可以打印报错
return -1; //异常退出
}
//定位文件
/* ret = lseek(fd,3,SEEK_SET);//文件头
printf("ret_lseek:%d\n",ret);//3
ret = lseek(fd,4,SEEK_CUR);//文件当前位置
printf("ret_lseek:%d\n",ret);//7
ret = lseek(fd,-4,SEEK_END);//文件尾
printf("ret_lseek:%d\n",ret);//10 */
/*
小知识点:利用文件的尾坐标来计算文件的大小
*/
ret = lseek(fd,0,SEEK_END);//文件尾
printf("file_size:%d\n",ret);
//读文件
char buf[1024] = {0}; // 定义buf的时候一定要清空
//bzero(buf,sizeof(buf));
//memset(buf,0,sizeof(buf));
ret = read(fd,buf,20);
printf("buf:%s ret_read:%d\n",buf,ret);
//关闭文件
close(fd);
return 0; //正常退出
}