std::ifstream/FILE*是否可以更改大小
Can a std::ifstream/FILE* change size?
假设我有以下代码(只需打开一个文件,获取其大小,并一次性读取):
std::ifstream file(path, std::ios_base::binary | std::ios_base::ate);
std::istream::streampos file_size = file.tellg();
file.seekg(0);
char* buffer = new char[file_size];
file.read(buffer, file_size);
文件是否可以在file.tellg()
和file.read()
调用之间更改大小(即另一个程序修改文件)?也就是说,如果file.read()
成功,是否保证file.gcount() == file_size
?
将其扩展到C*(即执行fopen("rb")
、fseek()
、ftell()
、rewind()
、fread()
),如果fread()
成功,它是否总是返回文件大小(如ftell()
之前报告的)?
我倾向于将其定义为实现,但我很好奇C++标准(或C标准,因为C++标准指的是FILE
相关函数)是否在这里做出了任何保证。
*我在C++中工作,有两种方法可以用来处理文件:std::fstream
和FILE*
。C++标准在FILE*
函数方面遵循C标准,这就是为什么我在这里明确提到C
我认为这取决于您打开的文件类型和操作系统的功能。
为了使读取不按预期进行,文件必须在ftell
和fread
之间收缩。您可以让另一个进程使用ftruncate
来完成此操作。我找不到任何信息来说明打开文件的任何其他进程会发生什么。但我不希望他们一定能够读取过去的数据。
以下实验表明,std::ifstream
/FILE*
在读取时确实可以改变大小:
写入1.cpp:
#include <fstream>
int main() {
for (;;) {
std::ofstream file("file.txt", std::ios_base::binary | std::ios_base::trunc);
file.flush();
file << "Hello world!n";
}
}
Reader1.cpp:
#include <iostream>
#include <fstream>
int main() {
for (;;) {
std::ifstream file("file.txt", std::ios_base::binary | std::ios_base::ate);
std::streamsize file_size = file.tellg();
if (!file || file_size == -1) continue;
file.seekg(0);
char* buffer = new char[file_size];
file.read(buffer, file_size);
delete [] buffer;
if (file.gcount() != file_size) {
std::cout << file.gcount() << " != " << file_size << std::endl;
break;
}
}
}
编译Writer1.cpp
和Reader1.cpp
并同时运行它们最终得到0 != 13
,这表明std::ifstream
确实可以在tellg()
和read()
之间改变大小。
Writer2.cpp:
#include <iostream>
#include <fstream>
#include <cstdio>
int main() {
for (;;) {
FILE* file = fopen("file.txt", "wb");
fflush(file);
fwrite("Hello world!n", 1, 13, file);
fclose(file);
}
}
Reader2.cpp:
#include <iostream>
#include <cstdio>
int main() {
for (;;) {
FILE* file = fopen("file.txt", "rb");
if (!file) continue;
fseek(file, 0, SEEK_END);
long file_size = ftell(file);
if (file_size == -1) {
fclose(file);
continue;
}
rewind(file);
char* buffer = new char[file_size];
size_t nread = fread(buffer, 1, file_size, file);
fclose(file);
delete [] buffer;
if (nread != file_size) {
std::cout << nread << " != " << file_size << std::endl;
break;
}
}
}
同样,编译Writer2.cpp
和Reader2.cpp
并同时运行它们最终会产生0 != 13
,这表明FILE*
确实可以在ftell()
和fread()
之间改变大小。
有趣的是,std::ifstream
对我来说比FILE*
失败得更快。这些测试是在带有clang 3.5的OS X 10.9.5上完成的。
- 在提升multi_index容器中,是否定义了"default index"?
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 检查输入是否不是整数或数字
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- ifstream什么都没读
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 是否可以在没有真实文件的情况下创建 ifstream
- 关于使用ifstream在C 中确定文件是否存在的问题
- 是否有任何模拟框架可以模拟std :: ifstream和其他I/O库
- 我是否以不良方式使用ifstream :: fail()方法
- 我是否必须在每次使用 ifstream 读取后寻找
- std::ifstream/FILE*是否可以更改大小
- 如何检查 ifstream 是否是 C++ 中文件的结尾
- 有没有一种优雅的方法来确定ifstream是否附加到标准
- “eof”是否为“ifstream”的有效状态
- c++ std::ifstream:检查是否留下字符供读取
- ifstream在二进制模式下打开是否需要ios::in?
- 是否可以将任何类对象作为测试表达式传递给任何测试表达式,例如if,while like ifstream对象
- 正在检查是否使用ifstream成功打开了文件