查找二进制文件的大小,函数 tellg() returns -1
Find size of binary file, function tellg() returns -1
我写了一个函数来初始化 FileDataTransfer 对象的一些字段,还可以找到文件的大小。
这是一个代码:
bool FileTransferData::initialize(const string& fileName, string& errMsg)
{
if (this->transferInProgress)
{
errMsg = "\nFile Transfer already in progress. File Transfer Request denied.\a";
return false;
}
this->inFileStream.open(fileName, ios::binary | ios::ate);
if (!inFileStream.is_open())
{
errMsg = "\nRequested file: " + fileName + " does not exist or was not found.\a";
return false;
}
this->fileName = fileName;
this->fileSize = (int)this->inFileStream.tellg();
this->inFileStream.seekg(0);
this->fileOffset = 0;
this->transferInProgress = true;
return true;
}
但是字段this->fileSize在我的函数完成后变为-1,我认为tellg() returns -1,但为什么?
std::istream::tellg
的 -1
值表示一个错误,您可以使用 std::ios::fail
和 std::ios::bad
成员函数检查该错误:
If either the stream buffer associated to the stream does not support the operation, or if it fails, the function returns -1.
我无法重现该错误,因此我打算向您推荐另一种方法。您使用的平台知道文件的大小以及更多相关信息(上次访问时间等)。以下示例显示了如何以平台相关的方式确定文件的大小(就像 boost::filesystem::file_size
一样):
#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#endif
#include <cstdint>
intmax_t fsizeof(const std::string& fileName) {
intmax_t fileSize = -1;
#ifdef _WIN32
WIN32_FILE_ATTRIBUTE_DATA fileData;
if(GetFileAttributesEx(fileName.c_str(), GetFileExInfoStandard, &fileData) &&
!(fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
fileSize = fileData.nFileSizeHigh;
fileSize <<= sizeof(fileData.nFileSizeLow) * 8;
fileSize += fileData.nFileSizeLow;
}
#else
struct stat fileStat;
if(stat(fileName.c_str(), &fileStat) == 0 && S_ISREG(fileStat.st_mode))
fileSize = fileStat.st_size;
#endif
return fileSize;
}
你可以这样得到一个文件的大小
long long filesize(const char *fname)
{
int ch;
FILE *fp;
long long answer = 0;
fp = fopen(fname, "rb");
if(!fp)
return -1;
while( (ch = fgetc(fp)) != EOF)
answer++;
fclose(fp);
return answer;
}
它是可移植的,虽然它会传递文件,但通常您无论如何都必须传递文件,因此您不会破坏函数的大 O 效率。另外 fgetc() 针对缓冲进行了高度优化。
我写了一个函数来初始化 FileDataTransfer 对象的一些字段,还可以找到文件的大小。
这是一个代码:
bool FileTransferData::initialize(const string& fileName, string& errMsg)
{
if (this->transferInProgress)
{
errMsg = "\nFile Transfer already in progress. File Transfer Request denied.\a";
return false;
}
this->inFileStream.open(fileName, ios::binary | ios::ate);
if (!inFileStream.is_open())
{
errMsg = "\nRequested file: " + fileName + " does not exist or was not found.\a";
return false;
}
this->fileName = fileName;
this->fileSize = (int)this->inFileStream.tellg();
this->inFileStream.seekg(0);
this->fileOffset = 0;
this->transferInProgress = true;
return true;
}
但是字段this->fileSize在我的函数完成后变为-1,我认为tellg() returns -1,但为什么?
std::istream::tellg
的 -1
值表示一个错误,您可以使用 std::ios::fail
和 std::ios::bad
成员函数检查该错误:
If either the stream buffer associated to the stream does not support the operation, or if it fails, the function returns -1.
我无法重现该错误,因此我打算向您推荐另一种方法。您使用的平台知道文件的大小以及更多相关信息(上次访问时间等)。以下示例显示了如何以平台相关的方式确定文件的大小(就像 boost::filesystem::file_size
一样):
#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#endif
#include <cstdint>
intmax_t fsizeof(const std::string& fileName) {
intmax_t fileSize = -1;
#ifdef _WIN32
WIN32_FILE_ATTRIBUTE_DATA fileData;
if(GetFileAttributesEx(fileName.c_str(), GetFileExInfoStandard, &fileData) &&
!(fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
fileSize = fileData.nFileSizeHigh;
fileSize <<= sizeof(fileData.nFileSizeLow) * 8;
fileSize += fileData.nFileSizeLow;
}
#else
struct stat fileStat;
if(stat(fileName.c_str(), &fileStat) == 0 && S_ISREG(fileStat.st_mode))
fileSize = fileStat.st_size;
#endif
return fileSize;
}
你可以这样得到一个文件的大小
long long filesize(const char *fname)
{
int ch;
FILE *fp;
long long answer = 0;
fp = fopen(fname, "rb");
if(!fp)
return -1;
while( (ch = fgetc(fp)) != EOF)
answer++;
fclose(fp);
return answer;
}
它是可移植的,虽然它会传递文件,但通常您无论如何都必须传递文件,因此您不会破坏函数的大 O 效率。另外 fgetc() 针对缓冲进行了高度优化。