目录
重定向打开文件
文件IO
概念
特点
函数
1.打开文件
2.关闭文件
3.读写文件
read
write
4.文件定位操作
重定向打开文件
FILE * freopen(const char *pathname, const char *mode, FILE* fp)
功能:将指定的文件流重定向到打开的文件中
参数:path:文件路径
mode:打开文件的方式(同fopen)
fp:文件流指针
返回值:成功:返回文件流指针
失败:NULL
freopen案例:
#include <stdio.h>
int main(int argc, char const *argv[])
{
printf("hello\n");
freopen("./test.c", "w", stdout);
printf("world\n");
freopen("/dev/tty", "w", stdout); // /dev/tty表示终端
printf("hello world\n");
return 0;
}
文件IO
概念
在可移植操作系统接口中定义的一组输入输出的函数
特点
1.没有缓冲机制,每次操作都会经过系统调用,效率比较低
2.围绕文件描述符,文件描述符是非负整数,0、 1、 2
3.默认打开三个文件描述符,0(标准输入)、1(标准输出)、2(标准错误)
4.除目录外其他任意类型文件都可以操作
函数
1.打开文件
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags, ...);
功能:打开文件
参数:pathname:文件路径名
flags:打开文件的方式
O_RDONLY:只读
O_WRONLY:只写
O_RDWR:可读可写
O_CREAT:创建
O_TRUNC:清空
O_APPEND:追加
返回值:成功:文件描述符
失败:-1
当第二个和参数存在O_CREAT,我们就需要写第三个参数:你要创建文件的权限
open案例:
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
int fd, fd1;
fd = open("./test.c", O_CREAT | O_RDONLY | O_TRUNC, 0666);
if (fd < 0)
{
perror("open err");
return -1;
}
printf("fd:%d\n", fd);
return 0;
}
实际文件权限计算方式:指定的权限值 & (~umask),umask=002
补充
1.当第二个参数中有O_CREAT选项时,需要给open函数传递第三个参数,指定创建文件的权限 ,open(file, xx|O_CREAT|xx, 0666);
2.实际创建出来的文件权限为:指定权限值&(~umask) //umask为文件权限掩码,通过umask命令可以查看
3.打开文件方式对应表:
2.关闭文件
int close(int fd);
参数:fd:文件描述符
close示例:
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
int fd;
fd = open("./test.c", O_CREAT | O_RDONLY | O_TRUNC, 0666);
close(fd);
return 0;
}
3.读写文件
read
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
功能:从一个已打开的可读文件中读取数据
参数:fd 文件描述符
buf 存放位置
count 期望的个数
返回值:成功:实际读到的个数
返回-1:表示出错,并设置errno号
返回0:表示读到文件结尾
write
ssize_t write(int fd, const void *buf, size_t count);
功能:向指定文件描述符中,写入 count个字节的数据。
参数:fd 文件描述符
buf 要写的内容
count 期望值
返回值:成功:实际写入数据的个数
失败 : -1
补充:在读和写一起使用时,一般write的字符个数指定为read的返回值,“读多少写多少”
读写文件案例:
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
int fd;
char buf[32] = {""};
fd = open("./test.c", O_RDWR);
if (fd < 0)
{
perror("open err");
return -1;
}
printf("fd:%d\n", fd); // 3
write(fd, "hello", 5);
lseek(fd, 0, SEEK_SET);
// 不同于标准I0,文件I0是指定多少个字符就获取多少个字符
ssize_t s = read(fd, buf, 5);
printf("%s\n", buf);
printf("%ld\n", s); // 打印的是实际获取到的字符个数
// 关闭文件
close(fd);
return 0;
}
4.文件定位操作
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
功能:设定文件的偏移位置
参数:fd:文件描述符
offset偏移量
正数:向文件结尾位置移动
负数:向文件开始位置
whence 相对位置
SEEK_SET 开始位置
SEEK_CUR 当前位置
SEEK_END 结尾位置
返回值:成功:文件的当前位置
lseek案例:
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
int fd;
char buf[32] = "";
fd = open("./test.c", O_RDWR | O_TRUNC);
if (fd < 0)
{
perror("open err");
return -1;
}
// 相对于开头偏移10个字符
lseek(fd, 10, SEEK_SET);
write(fd, "a", 1);
off_t s = lseek(fd, 0, SEEK_END);
printf("%ld\n", s);
// 关闭文件
close(fd);
return 0;
}