C++中创建指定大小空文件最推荐用C++17的std::filesystem::resize_file(),它自动创建或调整文件大小为指定字节数;若不支持C++17,则Linux用truncate()、Windows用CreateFile()+SetEndOfFile(),均需确保路径存在且有写权限。

用 std::ofstream 创建空文件并截断为指定大小
直接创建“指定大小的空文件”,C++ 标准库没有一键函数,必须先创建文件,再调整其长度。最可靠的方式是打开文件、写入一个字节、然后用 truncate()(POSIX)或 SetFileInformationByHandle()(Windows)收缩/扩展——但跨平台时更稳妥的做法是:用 std::ofstream 创建文件后,立即用系统 API 设置大小。
注意:std::ofstream("file.bin", std::ios::out) 默认会清空已有文件,但不会改变文件长度;若文件已存在且比目标尺寸小,仅打开不写内容会导致文件仍保持原大小。
- Linux/macOS:调用
truncate(),头文件<unistd.h> - Windows:用
CreateFile()+SetEndOfFile(),或 C++17 起可用std::filesystem::resize_file()(推荐) - 若只用标准库且不依赖 C++17,
std::ofstream无法直接设大小,必须搭配系统调用
C++17 起用 std::filesystem::resize_file() 最简洁
这是目前最干净、可移植的方案,只要编译器支持 C++17 且链接了 std::filesystem(GCC 需加 -lstdc++fs,Clang 同理)。
#include <filesystem>
namespace fs = std::filesystem;
// 创建空文件并设为 1024 字节
fs::create_directories("path/to");
std::ofstream("path/to/empty.bin", std::ios::out).close(); // 确保文件存在
fs::resize_file("path/to/empty.bin", 1024); // 自动创建或调整大小
关键点:
立即学习“C++免费学习笔记(深入)”;
-
fs::resize_file()对不存在的文件会自动创建(内容全零),无需提前ofstream::close() - 若目标路径含多级目录,必须先用
fs::create_directories(),否则抛std::filesystem::filesystem_error - 传入大小为 0 是合法的,结果是空文件(长度 0)
Windows 下不依赖 C++17 的替代方案
若项目卡在 C++11/14,或需精确控制句柄行为(比如避免权限问题),应直接调 Windows API。
#include <windows.h>
#include <string>
bool create_sized_file(const std::string& path, size_t size) {
HANDLE h = CreateFileA(path.c_str(), GENERIC_WRITE,
0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
if (h == INVALID_HANDLE_VALUE) return false;
LARGE_INTEGER li;
li.QuadPart = static_cast<LONGLONG>(size);
bool ok = SetFilePointerEx(h, li, nullptr, FILE_BEGIN) &&
SetEndOfFile(h);
CloseHandle(h);
return ok;
}
常见坑:
-
CREATE_ALWAYS会覆盖已有文件,CREATE_NEW则失败(如果文件已存在) - 未检查
SetFilePointerEx()返回值,导致SetEndOfFile()在错误位置生效 - 忘记
CloseHandle(),造成句柄泄漏(尤其循环中多次调用)
Linux 下用 truncate() 注意权限和路径
POSIX 方案简单,但对路径合法性更敏感,且要求父目录存在、有写权限。
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
int fd = open("data.bin", O_CREAT | O_WRONLY, 0644);
if (fd != -1) {
close(fd);
if (truncate("data.bin", 4096) == -1) {
// 处理 errno,如 ENOENT(目录不存在)、EACCES(权限不足)
}
}
典型错误现象:
-
truncate()返回 -1 且errno == ENOENT:父目录没建好,得先mkdir -p或用mkdir()逐级创建 - 用
O_TRUNC打开文件再write()写满,看似可行,但写入过程慢且不必要——truncate()是元数据操作,瞬间完成 - 误用
ftruncate()传入错误的 fd(比如open()失败后仍调用),导致未定义行为
跨平台项目里,std::filesystem::resize_file() 覆盖了绝大多数场景;真要手撸系统调用,务必检查每一步的返回值——尤其是目录是否存在、文件是否可写、目标大小是否超出文件系统限制。


















