cst一改参数就报错(CStdioFile无法读取2GB以上的文件的解决方法)
cst一改参数就报错(CStdioFile无法读取2GB以上的文件的解决方法)又绕了好多弯路,还是没找到原因。但是2.02GB,离4GB还很远呢,而且我们是64位系统。然后经过各种尝试,也没有解决。后来看了一下文件的大小,2.02GB。隐约记的32位系统,单文件不能超过4GB。
最近被一个大文件给难住了!
在数字的海洋里找啥呢
之前开发好的功能,一直运行得蛮好的,这两天来了个新数据,突然不行了!
经过调试,发现在通过CStdioFile读取文件的长度的时候,出现了异常。
然后经过各种尝试,也没有解决。
后来看了一下文件的大小,2.02GB。
隐约记的32位系统,单文件不能超过4GB。
但是2.02GB,离4GB还很远呢,而且我们是64位系统。
又绕了好多弯路,还是没找到原因。
后来去网上一查,才知道CStdioFIle处理的文件上限是2GB。
不管是32位系统,还是64位系统!
百度了好一阵子,找到一个从CFile派生,重写几个函数,解决CFile不能读取大文件的方法。
但是这个方法不适用于CStdioFile。
无奈继续查找,后来在Bing国际版本上,搜索【CStdioFile 2GB】关键字,找到一篇StackoverFlow上面的文章。
stackoverflow
文章给出了解决办法:
1.不使用CStdioFile,找其他方法代替
2.重写CStdioFile的几个方法,以支持大文件,作者还给出了具体的代码,可以直接使用
我当然是采用了后者,这样不需要修改业务代码。
把作者的代码拿过来,测试了一下,OK,搞定了。
不得不说,没有StackOverFlow解决不了的问题,还是有一定道理的。
大家遇到解决不了的开发问题,记得不要在百度里面死磕,去国外的站点试试,耐心一点,一般会有解决办法的。
另外就是MFC的东西,要少用。现在国产化势在必行, 一定要用标准C 来编程。
下面附上stackoverflow的连接及代码
https://stackoverflow.com/questions/62097271/cstdiofile-cannot-work-with-files-larger-than-2gb
代码,亲测可用!
头文件:
#pragma once
#include <afx.h>
class CStdioFileExt : public CStdioFile
{
DECLARE_DYNAMIC(CStdioFileExt)
public:
ULONGLONG GetPosition() const override;
ULONGLONG GetLength() const override;
ULONGLONG Seek(LONGLONG lOff UINT nFrom) override;
};
实现文件:
#include "CStdioFileExt.h"
ULONGLONG CStdioFileExt::GetPosition() const
{
ASSERT_VALID(this);
ASSERT(m_pStream != NULL);
auto const pos = _ftelli64(m_pStream);
if (pos == -1L)
AfxThrowFileException(CFileException::invalidFile _doserrno m_strFileName);
return static_cast<ULONGLONG>(pos);
}
ULONGLONG CStdioFileExt::GetLength() const
{
ASSERT_VALID(this);
auto const ncurrent = _ftelli64(m_pStream);
if (nCurrent == -1L)
AfxThrowFileException(CFileException::invalidFile _doserrno m_strFileName);
auto nResult = _fSeeki64(m_pStream 0 SEEK_END);
if (nResult != 0)
AfxThrowFileException(CFileException::badSeek _doserrno m_strFileName);
auto const nLength = _ftelli64(m_pStream);
if (nLength == -1L)
AfxThrowFileException(CFileException::invalidFile _doserrno m_strFileName);
nResult = _fseeki64(m_pStream nCurrent SEEK_SET);
if (nResult != 0)
AfxThrowFileException(CFileException::badSeek _doserrno m_strFileName);
return static_cast<ULONGLONG>(nLength);
}
ULONGLONG CStdioFileExt::Seek(LONGLONG lOff UINT nFrom)
{
ASSERT_VALID(this);
ASSERT(nFrom == begin || nFrom == end || nFrom == current);
ASSERT(m_pStream != NULL);
if (_fseeki64(m_pStream lOff nFrom) != 0)
AfxThrowFileException(CFileException::badSeek _doserrno m_strFileName);
auto const pos = _ftelli64(m_pStream);
return static_cast<ULONGLONG>(pos);
}
IMPLEMENT_DYNAMIC(CStdioFileExt CStdioFile)