查找二进制文件的大小,函数 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::failstd::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() 针对缓冲进行了高度优化。