系统调用:内核提供的函数让用户能访问内核数据。
用户区和内核区不能直接访问,需要借助系统调用。(开销大)
文件描述符:
0 标准输出
1标准输出
2标准错误
文件指针:
stdin
stdout
stderr
一.打开文件
1.加头文件:man 2 open
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
2.使用:
int open(const char *pathname, int flags);
第一个参数:要打开的文件名
第二个参数:打开方式 O_RDONLY(只读形式), O_WRONLY(只写形式), or O_RDWR(读写形式)
int open(const char *pathname, int flags, mode_t mode);
第一个参数:要打开的文件名
第二个参数:打开方式 O_RDONLY(只读形式), O_WRONLY(只写形式), or O_RDWR(读写形式)其中一个
可选部分:
O_CREAT:如果打开的文件不存在,则自动创建这个文件 O_TRUNC:如果被打开的文件存在并且是以可写的方式打开,则清空文件原有的内容
O_APPEND:打开之后文件的读写位置被置于文件的末尾
第三个参数:文件的权限,可用8进制表示 ,例如:0766,0755等。
最终文件的权限:mode & ~umask
3.返回值:打开文件成功,返回文件描述符(默认选择当前可用的最小文件描述符),失败返回-1
注意:最后一定要关闭文件:close(文件描述符)
二.读文件
1.加头文件 man 2 read
#include <unistd.h>
2.使用:
ssize_t read(int fd, void *buf, size_t count);
第一个参数:文件描述符
第二个参数:读取到的数据要放入的缓冲区
第三个参数:要读取的字节数
3.返回值:成功返回读取到的字节数,若已经到文件结尾则返回0,若出错则返回-1
注意:读取一个完整的大数据
例如:
int main()
{
int fd = open("test.c", O_RDONLY);
if (-1 == fd)
{
perror("打开test.c文件失败");
return -1;
}
char buf[SIZE+1];
char *p = buf;//用指针来使得下一次读到的数据存放在前一次读的后面
int count = SIZE;
while (count)
{
ssize_t ret = read(fd, p, count);
if (-1 == ret)
{
perror("读取数据失败");
return -1;
}
printf ("ret = %ld\n", ret);
count -= ret;
p += ret;
}
buf[SIZE] = 0;
printf ("%s",buf);
close(fd);
return 0;
}
三.写文件
1.以只读方式打开文件 O_WRONLY/ O_CREAT
2.使用:
ssize_t write(int fd, const void *buf, size_t,count);
第一个参数:要写的文件描述符
第二个参数:要写的内容
第三个参数:要写的字节数
3.返回值:成功返回已写的字节数,出错返回-1
四.lseek:系统调用可以改变文件偏移量
1.头文件
#include <sys/types.h>
#include <unistd.h>
2.使用:
off_t lseek(int fd, off_t offset, int whence);
第一个参数:文件操作符
第二个参数:偏移量
第三个参数:
SEEK_SET:文件开始处
SEEK_CUR:文件当前位置
SEEK_END:文件结尾处
1.获取文件大小:将文件指针定到文件结尾
2.调整文件指针:helloworld===>helworld
3.创建大文件
方法1:
(1)将 lseek从开头定位到所要创建文件大小的位置
(2)在最后这个位置写入一个字符
方法2:
dd if=/dev/zero of=/dev/null bs = count =
方法3:
truncate :创建一个文件到指定的长度
truncate(文件名,文件大小) 此时文件必须要存在
也可以在终端直接敲命令:
例如:
truncate 文件名 -s 文件大小 若没有这个文件会创建一个
五.dup/dup2
文件描述符表中包括文件描述符标志和文件指针
(打开两次同一个文件,文件描述符表中文件描述符不相同,但是文件指针相同,文件指针指向的打开文件表某一项也不相同)
1.头文件:
#include <unistd.h>
2.使用:
int dup(int oldfd);
int dup2(int oldfd, int newfd);
将文件描述符表中指针部分,复制一份给newfd,若复制成功,则将newfd原来打开的文件关闭。
输出缓存区导出数据的条件:
(1)遇到换行
(2)遇到输出操作
(3)缓存区满
(4)手动清空 fflush(文件指针)==>将缓存区中的内容一次导入到内核区
(5)程序结束会自动清空缓冲区