目录
- 第一部分:文件编程
- 一.打开/创建文件
- 二.文件的写入操作
- 三.文件的读取
- 四.文件的光标
- 应用:计算文件的大小
- 第二部分:文件操作原理:
- 一.文件描述符
- 静态文件和动态文件
- 第三部分:文件编程小应用
- 1.实现CP命令
- 2.修改文件
- 3.写一个整数到文件
- 4.写一个结构体到文件
- 第四部分 标准C库对文件的操作
- 1.open和fopen的区别:
- 2.应用:
- 补充: 对参数的理解:
- 标准C库写一个结构体到文件
- 这里有一个问题:
- fputc (用的少)
- feop fgetc (用的少)
linux是通过编程来实现对文件的一系列操作
(创建文档 编辑文档 保存文档 关闭文档)
第一部分:文件编程
一.打开/创建文件
1.open函数
头文件:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
函数原型(2个):
int open(const char *pathname, int flags);
参数1:指向文件路径的字符串
参数2:权限:
O_RDONLY 只读打开 (用这个后续就不能write了)
O_WRONLY 只写打
O_RDWR 可读可写打开
int open(const char *pathname, int flags,mode_t mode);
参数3:也是权限。例如:0600
0600(可读可写)的解释:
可读 r 4
可写 d 2
可执行 x 1 0600 4+2=6
open一个文件时会返回一个文件描述符
2.creat(要创建的文件名,创建模式)
创建模式:
S_IRUSR 可读 宏:4
S_IWUSR 可写 宏:2
S_IXUSR 可执行 宏:1
S_IRWXU 可读可写可执行 宏:7
在/home/jmh/路径下创建一个file1
3.权限:
O_EXCL:若已经有该文件,还创建,则返回-1
O_CREAT:往文件尾部加东西
O_TRUNC:把之前所有的都清空,写上后加的东西
二.文件的写入操作
write(fd,buf要写的东西,东西的大小)
这个buf是个无类型的指针,使用时要注意强制转换
返回值是成功写入的字节数
头文件:#include <unisted.h>
三.文件的读取
头文件同write
read(fd,读到哪里,要读内容的大小)
返回值是成功读到的字节数
nread是读到的大小 readbuf是读到的内容
四.文件的光标
lseek (fd,偏移值,位置)
位置有三种:
SEEK_SET 头
SEEK_END尾
SEEK_CUR当前位置(负数往前走,正数往后走)
应用:计算文件的大小
第二部分:文件操作原理:
一.文件描述符
1.linux中,默认存在012这三个文件描述符
0:标准输入
1:标准输出
2:标准错误
例如:
read(0,buf,5)从标准输入那里去读,读到buf里
write (1,buf,5) 把buf写到标准输出里去
静态文件和动态文件
文件存在磁盘中,磁盘中的文件是静态文件。
open静态文件后,会在linux内核产生一个结构体来记录这个文件(此时是动态文件),read write操作都是对这里的文件进行操作。
第三部分:文件编程小应用
1.实现CP命令
实现cp src.c des.c
思路:
打开src.c
读src到buf
打开/创建des.c
把buf写到des.c
close两个文件
优化1:
0600前的权限那里可以加个O_TRUNC(如果目标文件有内容,则删掉,写新的)。
优化2:
1024那里,可以写成readbuf的大小,1024个字节不够准确,容易拷贝少了
解释:
(int argc char **argv)
argc:参数个数
**argv:数组指针,每一项都是个数组
注意:编译时,后面要加上 -o mycp
2.修改文件
test.config文件里:把LENG=3改成LENG=5
编译:
3.写一个整数到文件
4.写一个结构体到文件
第四部分 标准C库对文件的操作
1.open和fopen的区别:
1.来源
open是UNIX(包括linux)系统下的
fopen是C语言的库函数(就是只要是用的C语言,就有这个库)
2.移植性
fopen有良好的移植性,而open是UNIX系统调用,移植性有限(windows下不能运行)。
3.适用范围
某些特定情况下必须用open,fopen用来操作普通文件,比如之前写的open read write 都可以替代成fopen fread fwrite.
4.文件IO层次
open是低级IO fopen是高级IO
5.缓冲
缓冲文件系统:
fopen是在缓冲区中完成的,最终一次性写入到文件,内存到外存切换的次数就少,执行速度快,效率高
非缓冲文件系统:
open通过内核来操作文件,读写时会从用户态到内核态进行切换,多次调用就会导致效率很低。
open没缓冲,fopen有缓冲
2.应用:
FILE *fopen(文件路径,权限)
他的返回值是文件流,不同于open返回的文件描述符
权限:
r
r+
w
w+ 如果没有就创建
a
a+
size_t fwrite(缓冲区buf,数据类型的大小,数据的个数,文件指针)
size_t fread(缓冲区buf,数据类型的大小,数据的个数,文件指针)
优化:
fread和fwrite可以这么写:
(str , sizeof(char)*strlen(str) , 1 , fp); 一次就写(读)完那么多
补充: 对参数的理解:
read和write的返回值是成功读/写到的字节数。
而fread和fwrite的返回值受第三个参数影响。
但如果写了1个字节,读100,实际读的返回值也是1。
但写多少,实际写的返回值就是多少
标准C库写一个结构体到文件
这里有一个问题:
fwrite和fread第三个参数如果都写1,就没问题。
都写2 就会报下图的错。
不知道为什么,也不深究了,因为一般来说正常写都写1。
暂时的理解:读的时候,因为结构体里有int 有char 不知道是读int还是读char,不好分开读,就一次性把结构体读出来,所以读的第三个参数就填1
fputc (用的少)
输入数据(整型,字符,字符串…)到文件里
feop fgetc (用的少)
feop:
判断是否到了文件尾部。
没到尾部,返回值0
到尾部,返回值非0
fgetc:
一个一个字符的从文件里取出来