1. 删除文件
删除文件使用 remove() 函数,如果成功删除返回 0,不成功返回 -1。
void TestRemove(){
int result = remove("data/main.c");
printf("result: %d\n", result); // result: 0
int result2 = remove("data/main2.c");
printf("result: %d\n", result2); // result: -1
}
2. 文件重命名
使用 rename() 函数对文件进行重命名。与 remove() 函数返回值相同,如果重命名成功,函数返回 0,否则返回 -1。此外,在代码文件为 UTF-8 格式下,需要 setlocale(LC_ALL, "zh_CN.utf-8"),否则不能识别中文文件名。
void TestRename(){
setlocale(LC_ALL, "zh_CN.utf-8");
int result = rename("data/三国演义.txt", "data/sanguo.txt");
perror("result");
printf("result: %d\n", result); // result: 0
int result2 = rename("data/main2.c", "data/main.txt");
printf("result: %d\n", result2); // result: -1
}
3. 创建临时文件
使用 tmpfile() 函数创建临时文件,该文件会在程序退出时自动删除。此外,可通过强转指针类型获取临时文件的路径及文件名,也可使用 tmpnam() 函数进行获取。注意在使用 tmpnam() 函数时, buffer 的大小需要设定为宏 L_tmpnam,否则程序报错。
如代码所示,将 msvc 编译器中定义文件的源码取出,可以发现 FILE _public_file 和 结构体 WinFile 的起始地址是相同的,所以可将 FILE 的指针强转为 WinFile 的指针。而后利用 WinFile 中的 _tmpfname 获取文件的路径及文件名。
// 将 msvc 定义文件的源码取出
typedef struct __crt_stdio_stream_data
{
union {
FILE _public_file;
char *ptr;
};
char *_base;
int _cnt;
int _flags;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
} WinFile;
void TestTmpfile(){
FILE *file = tmpfile();
// 强转指针类型获取临时文件名及路径
WinFile *win_file = (WinFile *)file; // 将 file 的类型强转为 WinFile *
puts(win_file->_tmpfname); // C:\Users\gltzlike\AppData\Local\Temp\tzg.0
// 使用 tmpnam 获取临时文件名及路径
char buffer[L_tmpnam];
tmpnam(buffer);
puts(buffer); // C:\Users\gltzlike\AppData\Local\Temp\s510.0
fclose(file);
}
4. 获取文件大小
使用 struct stat 结构体中的 st_size 属性和 stat() 函数,可在传入文件名的情况下获取文件大小。
此代码在 msvc 编译器(无中文注释)的情况下成功运行,一旦加入中文注释,运行结果便会出错。在 mingw 编译器下可成功运行,结果与 msvc 编译器(无中文注释)的结果相同。
#include <sys/stat.h>
long GetFileSize(char const *filename){
struct stat st;
stat(filename, &st); // 将文件名传给 st 结构体
return st.st_size; // 获取文件大小,返回值为 long 类型,故仅支持少于 4GB 的文件
// struct _stat64 stat_64;
// stat(filename, &stat_64);
// return stat_64.st_size; // 返回值为 long long 类型,可支持 4GB 以上的文件
}
5. 判断是否为目录
使用 struct stat 结构体中的 st_mode 属性和 stat() 函数,以及宏 S_IFDIR,判断传入的文件名是否为目录。如果是目录,则返回非 0 值,如果不是目录,返回 0。
int IsDirectory(char const *filename){
struct stat st;
stat(filename, &st); // 将文件名传给 st 结构体
return st.st_mode & S_IFDIR; // 两者与运算,判断是否为目录
}