C编程语言
数据结构
Linux应用软件编程
-
文件操作
-
多任务(进程、线程)
-
网络编程
-
数据库
一、Linux文件操作
变量、数组、数据结构-------------》内存 :
-
读写数据速度快
-
程序执行结束、掉电数据丢失
-
空间小,价格昂贵
文件 --------------》外存(硬盘)
-
读写速度比内存慢
-
掉电数据不丢失
-
空间大,相对内存价格便宜
1.文件
xxx.c xxx.c xxx.txt xxx.jpg xxx.mp4 /dev/fb0 /etc
- 长期保存掉电不丢失的数据。
- Linux提供给应用层的硬件操作接口(一切皆文件)
2.Linux下文件类型
Linux下一切皆文件。
ls -l 文件名:查看文件具体信息
-rwxrwxr-x 1 linux linux 19856 Aug 14 19:20 a.out
-rw-rw-r-- 1 linux linux 6999 Aug 14 19:20 link.c
-rw-rw-r-- 1 linux linux 1240 Aug 14 19:20 link.h
-rw-rw-r-- 1 linux linux 1438 Aug 14 19:06 main.c
-rw-rw-r-- 1 linux linux 105 Aug 14 19:07 Makefile
7种文件类型
b block 块设备文件 如:存储类文件:硬盘
c charector 字符设备文件 如:鼠标、键盘、显示器...
d directory 目录文件 如:文件夹
- regular 普通文件 如:main.c xxx.h xxx.txt xxx.jpg a.out
l link 软连接文件 相当于快捷方式(符号链接)
s socket 套接字文件 网络编程
p pipe 管道文件 进程间通信
- 普通文件
二进制文件 : 0101010101 2026-->011111101010
a.out 9.png xxx.mp3
ASCII文件 :'h' 'e' 'l' 'l' 'o'
2026--->'2' '0' '2' '6'
cat
od -c
xxx.c xxx.h xxx.txt
3.Linux下文件操作方法
IO:input/output----》文件
- 标准IO:标准C库提供的文件操作接口,属于库函数。
#include <stdio.h>
printf();
scanf();
gets();
puts();
- 文件IO:Linux内核提供的文件操作接口,属于系统调用。
文件操作思想:
(1)打开文件
(2)读文件、写文件
(3)关闭文件
4.标准IO
(1)打开文件 : fopen()
(2)读文件、写文件 : fgetc()/fputc()、fgets()/fputs()、fread()/fwrite()
(3)关闭文件 : fclose()
1)man手册:
- Linux命令 ls cat
man ls
man 1 ls
- 系统调用
man open
man 2 open
- 库函数
fopen/fread/fclose
man fopen

文件流:文件在读写过程中所体现出来的字节流。
FILE
文件流指针:FILE *
标准IO文件操作面向文件流指针
2)fopen
FILE *fopen(const char *pathname, const char *mode);
功能:打开一个文件,并获得一个文件流指针
参数:
pathname:要打开的文件的文件名
mode:打开方式
"r" : 以只读方式打开,文件必须要存在
"r+" : 以读写方式打开,文件必须要存在
"w" : 以只写方式打开,文件不存在则创建,文件存在则清空
"w+" : 以读写方式打开,文件不存在则创建,文件存在则清空
"a" : 以只写方式打开,文件不存在则创建,写时追加写
"a+" : 以读写方式打开,文件不存在则创建,读从开头读,写从末尾写
返回值:
成功:FILE * (文件流指针)
失败:NULL
3)fclose
int fclose(FILE *stream);
功能:关闭文件
参数:
stream:已打开的文件的文件留置针
返回值:
成功:0
失败:EOF(-1)
注意:
只打开文件而使用完不关闭文件,造成文件描述符泄露。
4)fputc
int fputc(int c, FILE *stream);
功能:向文件中写入一个字符
参数:
c:要写入的字符或者字符对应的ASCII值
stream:要写入的文件的文件流指针
返回值:
成功:写入的字符
失败:EOF(-1)
putchar('a'); ===> fputc('a', stdout);
操作系统默认已打开的三个流:
FILE *
stdin :标准输入流 -------------》标准输入设备:键盘
stdout:标准输出流 -------------》标准输出设备:显示屏(终端)
stderr:标准出错流 -------------》标准出错设备:显示屏(终端)
5)fgetc
int fgetc(FILE *stream);
功能:从文件中读取一个字符
参数:
stream:要读取的文件的文件流指针
返回值:
成功:返回读到的字符
失败:EOF(-1)
读到文件末尾:EOF(-1)
练习:
-
使用fgetc将文件中的数据读出打印到终端
-
使用主函数传参的方式,实现一个cp的功能
int main(int argc, const char *argv\[\])
{
if (argc < 3)
{
printf("Usage: ./a.out srcfile dstfile\n");
return -1;
}
FILE *fpsrc = fopen(argv1, "r");
FILE *fpdst = fopen(argv2, "w");
if (NULL == fpsrc || NULL == fpdst)
{
printf("fopen error\n");
return -1;
}
int ret = 0;
while (1)
{
ret = fgetc(fpsrc);
if (EOF == ret)
{
break;
}
fputc(ret, fpdst);
}
fclose(fpsrc);
fclose(fpdst);
return 0;
}
主函数传参:
可以在程序运行时,利用命令行参数向主函数传参。
命令行传参:
./mycat 1.txt aaa bbb ccc
主函数形参:
argc : 命令行传递的参数个数 ----》4
argv : 保存多个char*类型指针的数组
argv0 ---->"./mycat"
argv1 ---->"1.txt"
argv2 ---->"aaa"
...
./mycat 1.txt
int main(int argc, const char *argv\[\])
{
if (argc < 2)
{
printf("Usage : ./a.out <filename>\n");
return -1;
}
argv0 ===>"./mycat";
argv1 ===>"1.txt"
}
6)fputs
int fputs(const char *s, FILE *stream);
功能:将一个字符串写入到文件,不包括'\0'字符(0)
参数:
s:要写入的字符串的首地址
stream:要写入的文件的文件流指针
返回值:
成功:>=0
失败:EOF(-1)
od -c 1.txt : 以字符方式显示文件中的内容
7)fgets
char *fgets(char *s, int size, FILE *stream);
功能:从文件中读取一行,遇到新行结束
参数:
s:存储读取到的数据的空间首地址
size:期待读到的字节数(最多size-1)
stream:要读的文件的文件流指针
返回值:
成功:返回s,存储数据的空间首地址
失败:NULL
到达文件末尾:NULL
fgets和fputs实现文件拷贝:
int file_cp(const char *srcfile, const char *dstfile)
{
FILE *fpsrc = fopen(srcfile, "r");
FILE *fpdst = fopen(dstfile, "w");
if (NULL == fpsrc || NULL == fpdst)
{
printf("fopen error\n");
return -1;
}
char buff1024 = {0};
while (NULL != fgets(buff, sizeof(buff), fpsrc))
{
fputs(buff, fpdst);
}
fclose(fpsrc);
fclose(fpdst);
return 0;
}
注意:
fgets和fputs主要用来按行操作ASCII文件,不能读写二进制文件(fputs无法写入0)。
gets和fgets区别:
(1)gets会读取终端输入的'\n'字符,在'\n'字符后面增减'\0';
gets不会读取'\n', 直接在字符串末尾加'\0'.
(2)gets是危险的,fgets是安全的,因为fgets有读取数据大小参数控制。
(3)fgets最多读取size-1个字节,最后位置留给'\0'。
scanf()
遇到空格、tab、换行,停止读入。
8)fwrite
size_t fwrite(const void *ptr, size_t size, size_t nmemb,
FILE *stream);
功能:向文件中写入大小是size的nmemb个元素
参数:
ptr:要写入的元素的首地址
size:每个元素的字节数
nmemb:要写入的元素的个数
stream:要写入的文件流指针
返回值:
成功:实际写入的元素个数
失败:< nmemb
9)fread
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:从文件中读取大小是size的nmemb个元素到ptr指针指向的内存空间
参数:
ptr:用来存储读到数据的空间首地址
size:每个元素的字节数
nmemb:希望读取的元素个数
stream:要读的文件流指针
返回值:
成功:返回实际从文件中读到的元素个数
当文件中不足一个元素时,返回0
10)流定位函数
(1)fseek()
int fseek(FILE *stream, long offset, int whence);
功能:重新定位流的位置
参数:
stream:要定位的文件流指针
offset:偏移量(字节)
whence:要偏移的相对位置
SEEK_SET : 从文件开头偏移
SEEK_CUR :从当前位置偏移
SEEK_END :从文件末尾偏移
返回值:
成功:0
失败:-1
(2)ftell()
long ftell(FILE *stream);
功能:获取流所在位置到文件开头的偏移量
(3)rewind()
void rewind(FILE *stream);
功能:将流复位到开头
- 求文件大小:
fseek(fp, 0, SEEK_END);
len = ftell(fp);
rewind(fp);
- 抢占磁盘空间
创建空洞文件,提前抢占磁盘空间