文件的操作无处不在,在linux系统中,基本上都是基于文件的。
系统中的文件分为文本文件和二进制文件。
文本文件:以ASCII码格式存放,每个字节存放一个ASCII码,代表一个字符。
二进制文件:直接按内存中存储的格式(二进制补码的形式)直接存放。
文件操作的几个函数:
1.打开文件
FILE * fopen(const char* filename, const char* mode);
打开一个filename文件,返回执行该文件缓冲区的FILE结构体指针。
mode详解:
标识 |
处理方式 |
当文件不存在时 |
当文件存在时 |
向文件输入 |
向文件输出 |
r |
读取 |
出错 |
打开文件 |
不能 |
可以 |
w |
写入 |
建立新文件 |
清空原有文件 |
可以 |
不能 |
a |
追加 |
建立新文件 |
在原有文件上追加 |
可以 |
不能 |
r+ |
读取/写入 |
出错 |
打开文件 |
可以 |
可以 |
w+ |
写入/读取 |
建立新文件 |
清空原有文件 |
可以 |
可以 |
a+ |
读取/追加 |
建立新文件 |
在原有文件上追加 |
可以 |
可以 |
在windows系统如读取的是二进制文件(linux不区分文件文件和二进制文件),需要加b,如rb等。
2.关闭文件
int fclose(FILE* fp);
关闭已打开的文件,同时会把缓冲区内的数据写入到文件,释放占用的系统资源。
成功:返回0,失败:返回EOF(-1)
3.写单字符到文件
int fputc(int ch, FILE * fp);
一次写一个字符到文件。
成功:返回写入的字符,失败:返回EOF
4.从文件里读单字符
int fgetc(FILE * fp);
一次从文件里读一个字符
成功:返回0,失败:返回EOF(读到文件末尾或失败均为EOF)
使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| FILE* fp = fopen("data.txt", "w+"); if (NULL == fp) { printf("open file error\n"); return -1; }
for (char ch = 'a'; ch <= 'z'; ch++) { printf("%c", fputc(ch, fp)); } printf("\n");
rewind(fp); //移动fp指针到文件开始
char ret; while((ret = fgetc(fp)) != EOF) { printf("%c\n", ret); }
fclose(fp);
|
5.写入一行字符
int fputs(char* str, FILE * fp);
把str指向的字符串写入到fp指向的文件中
成功:返回0,失败返回EOF
6.读取一行字符
char * fgets(char * buf, int length, FILE * fp);
从fp指向的文件中,至多读取length-1个字符,保存到buf中。
如读取length-1个字符结束前遇到\n或EOF,读取结束,读入后在最后加入'\0'字符。
成功:返回buf指针,出错或到文件结尾 返回NULL指针。
使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| FILE* fp = fopen("data.txt", "w+"); if (NULL == fp) { printf("open file error\n"); return -1; }
fputs("aaaaaa\n", fp); fputs("bbbbbb\n", fp); fputs("cccccc\n", fp); fputs("dddddd\n", fp);
rewind(fp); //移动fp指针到文件开始
char buf[1024] = {0}; while(fgets(buf, 1024, fp)) { printf("%s", buf); } fclose(fp);
|
7.写一块数据(二进制)
int fwrite(void* buffer, int num_bytes, int count, FILE * fp)
把buffer指向的数据写入fp指向的文件中
num_bytes:要写入字段的字节数; count:要写的字段个数
成功:返回写的字段数,出错或文件结束,返回0
8.读一块数据(二进制)
int fread(void* buffer, int num_bytes, int count, FILE * fp)
从fp指向的文件中读取数据到buffer中
num_bytes:要读取字段的字节数,count:要读的字段个数
成功:返回写的字段数,出错或文件结束,返回0
读取时要注意:以最小的单元进行读,或以写入的最小单元进行读
使用示例1:把结构体的数据保存到文件中,并读取文件打印出来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| #include <stdio.h>
typedef struct student { char name[32]; int age; char addr[32]; }Stu;
int main() { Stu stu[3] = {{"wpf", 18, "beijing"}, {"why", 20, "handan"}, {"wcc", 19, "tianjin"}}; FILE * fp = fopen("student.data", "wb+"); if (NULL == fp) { return -1; }
//写文件 for (int i=0; i<3; i++) { fwrite((void*)&stu[i], sizeof(Stu), 1, fp); }
rewind(fp); //移动文件指针到文件开始
//读文件 Stu stu1; while(fread((void*)&stu1, sizeof(Stu), 1, fp)) { printf("nmae:%s\n", stu1.name); printf("age:%d\n", stu1.age); printf("addr:%s\n", stu1.addr); printf("===============\n"); } fclose(fp); return 1; }
|
使用示例2:加密文件,解密文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| //加密函数 void encode(char* space , int n) { for (int i=0; i<n; i++) { space[i]++; } }
//解密函数 void decode(char* space , int n) { for (int i=0; i<n; i++) { space[i]--; } }
int main() { //加密 FILE *fpr = fopen("1.jpg", "rb+"); FILE *fpw = fopen("2.jpg", "wb"); if ((NULL == fpr) || (NULL == fpw)) { return -1; }
int res; char space[1024] = {0}; while((res = fread((void*)space, 1, 1024, fpr)) >0) { encode(space, res); fwrite((void*)space, 1, res, fpw); }
fclose(fpr); fclose(fpw);
//解密 FILE *fpr2 = fopen("2.jpg", "rb+"); FILE *fpw2 = fopen("3.jpg", "wb"); if ((NULL == fpr2) || (NULL == fpw2)) { return -1; }
while((res = fread((void*)space, 1, 1024, fpr2)) >0) { decode(space, res); fwrite((void*)space, 1, res, fpw2); }
fclose(fpr2); fclose(fpw2); return 1; }
|
9.文件指针偏移rewind
void rewind(FILE* stream)
将文件指针重新指向流的开头
10.文件指针偏移ftell
long ftell(FILE * stream)
获取文件流的当前读写位置。
返回当前读写位置偏离文件头部的字节数
11.文件指针偏移fseek
int fseek ( FILE * stream, long offset, int origin )
偏移文件指针
offset:偏移量
origin:偏移起始位置
#define SEEK_CUR 1 当前位置
#define SEEK_END 2 文件结尾
#define SEEK_SET 0 文件开头
成功:返回0, 失败:返回-1
使用示例:获取文件的大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| int main() { FILE *fp = fopen("1.jpg", "r"); if (NULL == fp) { return -1; }
if (fseek(fp, 0, SEEK_END) == 0) { long size = ftell(fp); printf("文件大小:%ld\n", size); } return 1; }
|