C++ 标准库的 C I/O 子集实现 C 风格流输入/输出操作。头文件提供通用文件支持并提供有窄和多字节字符输入/输出能力的函数,而 头文件提供有宽字符输入/输出能力的函数。
std::remove
int remove( const char* fname ); |
删除 fname
所指向的字符串所标识的文件。
若文件为当前进程或另一进程打开,则此函数行为是实现定义的。具体而言, POSIX 系统解链接文件名,到最后一个运行的进程关闭该文件为止,即使这是最后一个到文件的硬链接也不回收文件系统空间。 Windows 不允许删除该文件。
fname | - | 指向空终止字符串的指针,字符串含标识待删除文件的路径 |
成功时为 0 ,错误时为非零值。
POSIX 指定此函数行为的许多额外细节。
标准库亦定义接收一对迭代器和值的函数模板 std::remove ,此重载是标准算法之一。
#include
#include
#include
int main()
{
bool ok = static_cast(std::ofstream("file1.txt").put('a')); // 创建文件
if (!ok)
{
std::perror("Error creating file1.txt");
return 1;
}
std::cout << std::ifstream("file1.txt").rdbuf() << '\n'; // 打印格式
std::remove("file1.txt"); // 删除文件
bool failed = !std::ifstream("file1.txt");
if (failed)
{
std::perror("Error opening deleted file");
return 1;
}
return 0;
}
std::rename
int rename( const char *old_filename, const char *new_filename ); |
更改文件的文件名。以 old_filename
所指向的字符串标识该文件,以 new_filename
所指向的字符串标识新文件名。
若 new_filename
存在,则行为是实现定义的。
old_filename | - | 指向空终止字符串的指针,字符串含有标识要重命名的文件的路径 |
new_filename | - | 指向空终止字符串的指针,字符串含有文件的新路径 |
成功时为 0 ,错误时为非零值。
POSIX 规定此函数语义上的许多额外细节,它们由 std::filesystem::rename 复制到 C++ 中。
#include
#include
#include
int main()
{
bool ok{std::ofstream("from.txt").put('a')}; // 创建并写入文件
if (!ok)
{
std::perror("Error creating from.txt");
return 1;
}
if (std::rename("from.txt", "to.txt"))
{
std::perror("Error renaming");
return 1;
}
std::cout << std::ifstream("to.txt").rdbuf() << std::endl; // 打印文件
return 0;
}
std::tmpfile
std::FILE* tmpfile(); |
创建并打开临时文件。
该文件作为二进制文件、更新模式(如同为 std::fopen 以 "wb+"
模式)打开。该文件的文件名保证在文件系统中唯一。至少可以在程序的生存期内能打开 TMP_MAX 个文件(此极限可能与 tmpnam 共享,并可能为 FOPEN_MAX 进一步限制)。
若程序关闭文件,例如通过执行 std::fclose ,则自动删除文件。
若程序正常退出(通过调用 std::exit 、从 main 返回等,则亦自动删除所有通过调用 std::tmpfile
打开的文件。
若程序非正常退出,则是否删除这些临时文件是实现定义的。
(无)
关联的文件流,或若出现错误则为 NULL 。
一些实现(如 Linux )上,此函数确实从文件系统上创建、打开并立即删除该文件:只要被删除文件的文件开启描述符为程序所管理,该文件就会存在,但只要它被删除,其名就不会出现于任何目录中,从而再无其他进程能打开它。一旦文件描述符被关闭,或一旦程序终止(正常或异常),该文件所占有的空间将被文件系统回收。
一些实现(如 Windows )上要求提升的权限,因为该函数可能在系统目录中创建临时文件。
#include
#include
#include
int main()
{
std::FILE* tmpf = std::tmpfile();
std::fputs("Hello, world", tmpf);
std::rewind(tmpf);
char buf[6];
std::fgets(buf, sizeof buf, tmpf);
std::cout << buf << std::endl;
std::cout << "_ptr: " << tmpf->_ptr << std::endl;
std::cout << "_cnt: " << tmpf->_cnt << std::endl;
std::cout << "_base: " << tmpf->_base << std::endl;
std::cout << "_flag: " << tmpf->_flag << std::endl;
std::cout << "_file: " << tmpf->_file << std::endl;
std::cout << "_charbuf: " << tmpf->_charbuf << std::endl;
std::cout << "_bufsiz: " << tmpf->_bufsiz << std::endl;
std::cout << "_tmpfname: " << tmpf->_tmpfname << std::endl;
return 0;
}
std::tmpnam
char* tmpnam( char* filename ); |
创建不指名当前存在的文件的独有文件名,并将它存储于 filename
所指向的字符串。函数足以生成至多 TMP_MAX 个独有的文件名,但其一些或全部可能已在使用中,从而不适合作为返回值。
std::tmpnam
修改静态状态,而且不要求为线程安全。
filename | - | 指向足以保有至少 L_tmpnam 字节的字符数组的指针,将以数组为结果缓冲区。若传递空指针,则返回指向内部静态缓冲区的指针。 |
1) 若 filename
不是 NULL 则为 filename
。否则为指向内部静态缓冲区的指针。若不能生成适合的文件名,则返回空指针。若无法生成适合文件名,则返回 NULL 。
尽管 std::tmpnam
所生成的文件名难以猜测,却可能是另一个进程在 std::tmpnam
返回的时刻和此函程序试图使用返回的名称创建文件之间创建的文件的名称。标准函数 std::tmpfile 和 POSIX 函数 mkstemp 无此问题(仅使用 C 标准库创建一个独有的目录仍然要求使用 std::tmpnam
)。
POSIX 系统额外定义名称类似的函数 tempnam() ,它提供对目录的选择(默认是可选定义的宏 P_tmpdir )。
#include
#include
#include
int main()
{
std::string name1 = std::tmpnam(nullptr);
std::cout << "temporary file name: " << name1 << std::endl;
char name2[L_tmpnam];
if (std::tmpnam(name2))
{
std::cout << "temporary file name: " << name2 << std::endl;
}
return 0;
}