我必须在 [ios::binary] 模式下打开文件才能获得其大小
Must I open a file in [ios::binary] mode to get its size?
#include <fstream>
#include <string>
#include <cassert>
long long GetFileSizeA(const std::string& file_path)
{
return std::ifstream
{
file_path, std::ios::ate
}.tellg();
}
long long GetFileSizeB(const std::string& file_path)
{
return std::ifstream
{
file_path, std::ios::ate | std::ios::binary
}.tellg();
}
int main()
{
auto a = GetFileSizeA("~/test.log");
auto b = GetFileSizeB("~/test.log");
assert(a == b); // always true?
}
如果文件~/test.log
包含许多rn
序列,C++标准是否保证GetFileSizeA
与GetFileSizeB
相同?
该标准绝不保证两者相等(C 或 C++ 标准也不声明文件是否包含 rn
或 n
或 r
作为行尾,由操作系统和/或应用程序定义。标准 C 库,以及扩展的 C++ 库,保证如果你以文本模式读取文件,它会将任何实际的行尾转换为内部n
形式)。它也不能保证它并不总是相同的值。
更重要的是,您可能会发现,如果您阅读文件的某些部分并询问"我在哪里",则答案与作为二进制文件或ASCII文件读取是不同的。例如,如果您计划将文件映射到内存并将其处理为大字符串,而不转换换行符,那么您需要将其作为二进制文件执行。
C++标准没有这样的保证。
事实上,代码
std::ifstream{file_path, std::ios::ate | std::ios::binary}.tellg();
也不能保证按预期工作。基于文件的流的tellg()
操作归结为几个中间函数(std::basic_istream::tellg
-> std::basic_streambuf::pubseekoff
-> std::basic_filebuf::seekoff
),并使用"好像"公式来std::fseek()
。后者不需要支持相对于结束位置的二进制流中的搜索:
int fseek( std::FILE* stream, long offset, int origin );
设置文件流流的文件位置指示器。
如果流以二进制模式打开,则新位置正好 如果原点为
SEEK_SET
,如果原点为SEEK_CUR
,则从当前文件位置开始, 如果原点为SEEK_END
,则从文件末尾开始。二进制流 不需要支持SEEK_END
,特别是如果 输出空字节。
- 使用ios:ate写入到流会覆盖现有文件
- 'string'文件在带有C++文件的iOS插件上找不到
- 文件模式标志"ios::app"是否用于删除文件(如果文件已存在)?
- 使用 C++ iOS::ate 获取错误的文件大小
- 将文件从 iOS 应用程序加载到 C++ 对象中/<iostream>iOS 上的问题
- ios::app 和 ios::noreplace 模式在文件处理中有什么区别?
- 通过USB将文件从iOS设备传输到Windows PC
- 无法使用iOS:Ate在C 中写入文本文件
- 错误的同时将C 文件夹在iOS XCode项目中包括在内
- 使用 CMake 为 iOS 编译 dylib 文件
- 我必须在 [ios::binary] 模式下打开文件才能获得其大小
- 在iOS设备上找不到文件QT创建者C QstandardPaths :: StandardLocations(Qs
- 级联文件的iOS opencv filepath
- iOS和Android的C 中的文件操作
- 二进制文件:ios ::二进制文件不起作用
- 从工作iOS项目中导入.cpp文件并将其重命名为.mm问题
- 使用ExtAudioFileWrite for iOS将音频样本的缓冲区写入aac文件
- 为什么我打开一个没有std::ios::binary的文件(std::ifstream)
- 是否可以从IOS项目中的cpp文件获取文件路径
- OpenCV videoCapture 为 iOS 应用程序文档目录中的文件提供了错误的属性