C语言中文件操作主要有以下函数:
- fopen() :打开一个文件
- fclose():关闭一个文件
- fgetc():读取一个字符
- fgets():读取多个字符
- fputc():写入一个字符
- fputs():写入多个字符
- fread():二进制文件读取
- fwrite():二制进文件写入
- remove():删除文件
- rename():重命令文件
- access():判断文件是否存在
使用 fopen( ) 函数来创建一个新的文件或者打开一个已有的文件,这个调用会初始化类型 FILE 的一个对象,类型 FILE 包含了所有用来控制流的必要的信息。下面是这个函数调用的原型:
FILE *fopen( const char * filename, const char * mode );
访问模式 mode 的值可以是下列值中的一个:
模式 | 描述 |
---|---|
r | 打开一个已有的文本文件,允许读取文件。 |
w | 打开一个文本文件,允许写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会从文件的开头写入内容。 |
a | 打开一个文本文件,以追加模式写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会在已有的文件内容中追加内容。 |
r+ | 打开一个文本文件,允许读写文件。 |
w+ | 打开一个文本文件,允许读写文件。如果文件已存在,则文件会被截断为零长度,如果文件不存在,则会创建一个新文件。 |
a+ | 打开一个文本文件,允许读写文件。如果文件不存在,则会创建一个新文件。读取会从文件的开头开始,写入则只能是追加模式。 |
如果处理的是二进制文件,则需使用下面的访问模式来取代上面的访问模式:
"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"
Note:计算机的文件存储在物理上都是二进制.文本文件和二进制之分,其实是一个逻辑之分.C读写文本文件与二进制文件的差别仅仅体现在回车换行符.写文本时,每遇到一个'\n',会将其转换成'\r\n'(回车换行);读文本时,每遇到一个'\r\n',会将其转换成'\n'.
综合实例,对一个文件进行拆分与合并:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#define LOG(level,format,...) printf("%s:"format,level,__VA_ARGS__)
#define LOGI(format,...) LOG("INFO",format,__VA_ARGS__)
#define LOGE(format,...) LOG("ERROR",format,__VA_ARGS__)
long getFileSize(char* filePath){
FILE* file = fopen(filePath,"r");
fseek(file,0,SEEK_END);
long size = ftell(file);
fclose(file);
return size;
}
void separateFile(char* originFilePath,int file_num ){
FILE* file = fopen(originFilePath,"rb");
if (file == NULL){
LOGE("file(path=%s) open failed \n", originFilePath);
return;
}
long fileSize = getFileSize(originFilePath);
char** separateFilesNames = malloc(sizeof(char*)*file_num);
int i = 0;
for (; i < file_num;i++){
separateFilesNames[i] = malloc(sizeof(char)* 100);
sprintf(separateFilesNames[i], "%s.piece%d", originFilePath,i);
LOGI("generate file piece name:%s\n",separateFilesNames[i]);
}
int partSize = fileSize / file_num;
if (fileSize%file_num == 0){
for (i = 0; i < file_num; i++){
FILE* fr = fopen(separateFilesNames[i],"wb");
int j = 0;
for (; j < partSize; j++)
{
fputc(fgetc(file),fr);
}
fclose(fr);
}
}
else
{
int lastSize = fileSize - partSize*(file_num-1);
for (i = 0; i < file_num - 1; i++){
FILE* fr = fopen(separateFilesNames[i], "wb");
int j = 0;
for (; j < partSize; j++)
{
fputc(fgetc(file), fr);
}
fclose(fr);
}
FILE* fr = fopen(separateFilesNames[file_num-1], "wb");
int j = 0;
for (; j < lastSize; j++)
{
fputc(fgetc(file), fr);
}
fclose(fr);
}
fclose(file);
i = 0;
for (; i < file_num; i++){
free(separateFilesNames[i]);
}
free(separateFilesNames);
}
void mergeFile(char* mergeFileName, int file_num){
if (!_access(mergeFileName, 0)){//判断文件是否存在,不存在返回-1,即为真
LOGI("merge file is exist \n");
char newName[130];
strcpy(newName, mergeFileName);
strcat(newName, ".r.jpg");
rename(mergeFileName, newName);
}
FILE* file = fopen(mergeFileName, "wb");
char** separateFilesNames = malloc(sizeof(char*)*file_num);
int i = 0;
for (; i < file_num; i++){
separateFilesNames[i] = malloc(sizeof(char)* 100);
sprintf(separateFilesNames[i], "%s.piece%d", mergeFileName, i);
LOGI("find file piece name:%s\n", separateFilesNames[i]);
}
int status = 0;
for (i = 0; i < file_num; i++){
FILE* fbr = fopen(separateFilesNames[i],"rb");
if (fbr == NULL){
LOGE("file(path=%s) open failed \n", mergeFileName);
status = 1;
break;
}
long size = getFileSize(separateFilesNames[i]);
LOGI("handle file :%s,size =%ld\n", separateFilesNames[i],size);
int j = 0;
for (; j < size; j++)
{
fputc(fgetc(fbr),file);
}
fclose(fbr);
}
fclose(file);
if (status){
remove(mergeFileName);
}
i = 0;
for (; i < file_num; i++){
free(separateFilesNames[i]);
}
free(separateFilesNames);
}
void main(void){
char* originFile = "G:\\Temp\\timg.jpg";
int fileNum = 5;
//separateFile(originFile, fileNum);
//LOGI("separate file success!\n");
mergeFile(originFile, fileNum);
LOGI("merge file success!\n");
system("pause");
}