查找二进制文件的大小,函数tellg()返回-1

时间:2017-07-05 10:17:24

标签: c++ fstream

我编写了一个初始化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()返回-1,但是为什么?

2 个答案:

答案 0 :(得分:0)

std::istream::tellg-1值表示您可以使用std::ios::failstd::ios::bad成员函数检查错误:

  

如果与流关联的流缓冲区不支持该操作,或者如果它失败,则该函数返回-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;
}

答案 1 :(得分:-1)

你可以得到像这样的文件的大小

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;
}

它是便携式的,虽然它传递了文件,但通常你必须通过文件,所以你不会破坏你的功能的大效率。另外fgetc()针对缓冲进行了高度优化。