2010-03-07 132 views
0

我有一個2884765579字節文件。這雙具有這種功能,它返回數檢查:seekg()神祕失敗

size_t GetSize() { 
     const size_t current_position = mFile.tellg(); 
     mFile.seekg(0, std::ios::end); 
     const size_t ret = mFile.tellg(); 
     mFile.seekg(current_position); 
     return ret; 
    } 

我然後執行:

mFile.seekg(pos, std::ios::beg); 
// pos = 2883426827, which is < than the file size, 2884765579 

此設置failbit。 errno未更改。我可以採取哪些措施來解決此問題?


絕對相信說:

  • 的文件大小是真的2884765579
  • pos真的2884765579
  • 的failbit未.seekg之前設置()
  • 失敗位在.seekg()後面設置,並且在
  • ,之間沒有其他調用10
  • 打開文件與二進制標誌

編輯:萬一有人運行到同樣的問題..使用此代碼,我寫了許多頭痛少(僅在Windows工作)爲您:

class BinaryIFile 
{ 
public: 
    BinaryIFile(const string& path) : mPath(path), mFileSize(0) { 
     mFile = open(path.c_str(), O_RDONLY | O_BINARY); 

     if (mFile == -1) 
      FATAL(format("Cannot open %s: %s") % path.c_str() % strerror(errno)); 
    } 
    ~BinaryIFile() { 
     if (mFile != -1) 
      close(mFile); 
    } 

    string GetPath() const { return mPath; } 
    int64 GetSize() { 
     if (mFileSize) 
      return mFileSize; 

     const int64 current_position = _telli64(mFile); 
     _lseeki64(mFile, 0, SEEK_END); 
     mFileSize = _telli64(mFile); 
     _lseeki64(mFile, current_position, SEEK_SET); 

     return mFileSize; 
    } 

    int64 Read64() { return _Read<int64>(); } 
    int32 Read32() { return _Read<int32>(); } 
    int16 Read16() { return _Read<int16>(); } 
    int8 Read8() { return _Read<int8>(); } 
    float ReadFloat() { return _Read<float>(); } 
    double ReadDouble() { return _Read<double>(); } 

    void Skip(int64 bytes) { _lseeki64(mFile, bytes, SEEK_CUR); } 
    void Seek(int64 pos) { _lseeki64(mFile, pos, SEEK_SET); } 
    int64 Tell() { return _telli64(mFile); } 

    template <class T> 
    T Read() { return _Read<T>(); } 

    void Read(char *to, size_t size) { 
     const int ret = read(mFile, (void *)to, size); 
     if ((int)size != ret) 
      FATAL(format("Read error: attempted to read %d bytes, read() returned %d, errno: %s [we are at offset %d, file size is %d]") % size % ret % strerror(errno) % Tell() % GetSize()); 
    } 

    template <class T> 
    BinaryIFile& operator>>(T& val) { val = _Read<T>(); return *this; } 

private: 
    const string mPath; 
    int mFile; 
    int64 mFileSize; 

    template <class T> 
    T _Read() { T ret; if (sizeof(ret) != read(mFile, (void *)&ret, sizeof(ret))) FATAL("Read error"); return ret; } 
}; 
+0

'pos'是什麼類型? – jamesdlin 2010-03-07 03:05:22

+0

現在真正的問題是:你如何在Windows上獲得64位文件位置(除了切換到64位操作系統)。我無法幫到那裏,對不起。 – Tronic 2010-03-07 03:10:06

+0

是的,那是你的問題。帶有一個參數的'seekg'需要一個'streampos'參數,'seekg'有兩個'streamoff'參數。後者必須簽名。 – jamesdlin 2010-03-07 03:13:09

回答

2

您可以在給定位置之前看到kg,所以pos被簽名。嘗試使用大小爲0x7fffffff和0x80ffffff的文件,看看後者是否觸發問題,這是我的猜測。

+0

哇謝謝我沒有想到這一點!你知道是否有64位尋道功能?我知道有C,seek64或類似的(不是標準的),但是C++ - Windows呢? – 2010-03-07 03:08:37

+0

在C++中,64位版本可能(並可能會)通過重載實現,因此您可以先嚐試使用64位類型來查看您的實現是否提供了它們。 – jamesdlin 2010-03-07 03:11:46

+0

不是Windows上的專家,但我猜你將不得不使用他們的操作系統專用接口。他們在網上有相當廣泛的文件。 – paul 2010-03-07 03:13:21