【发布时间】:2012-09-09 15:24:39
【问题描述】:
正如标题所说,我在尝试打开文件进行二进制写入时遇到此错误(模式似乎无关紧要)。
我的应用程序使用 libev 来处理套接字(非阻塞/epoll 后端),并且在解析客户端数据包时,我希望在某个点收到文件上传消息以开始将我从服务器获取的磁盘数据写入磁盘。
我无法在 Google 上搜索任何有关 EAGAIN(Resource temporarily unavailable) 消息和文件打开的信息。
这些是我尝试过的方法:
-
fopen( ... ) 返回
EAGAIN - 使用 ofstream/fstream 的 open(...) 通过在堆上创建它们(新)返回
EAGAIN - 静态使用 ofstream/fstream 的 open(...) 作为类成员 (
ofstream m_ofFile;) 有效,但编译器会生成调用 ofstream 析构函数并在退出类方法 im 调用之前关闭文件的代码em>.open 来自。现在这与我的 C++ 知识相矛盾,对于作为类类型的类成员,在类所有者之前调用析构函数..
编辑:
@Joachim
你是对的,我并没有真正得到这个错误..(方法#1。很快将再次测试方法#2)。文件定期打开,我得到常规文件*。这发生在我班级的 Init(...) 函数中,但是当我稍后在 m_hFile 上调用 OnFileChunk 时,m_hFile 为 0,因此我无法写入它。这是完整的类代码:
class CFileTransferCS
{
wstring m_wszfile;
wstring m_wszLocalUserFolderPath;
int m_nChunkIndex;
int m_nWrittenBytes;
int m_nFileSize;
FILE* m_hFile;
CFileTransferCS( const CFileTransferCS& c ){}
CFileTransferCS& operator=( const CFileTransferCS& c ){}
public:
CFileTransferCS( );
CFileTransferCS( wstring file, uint32_t size );
void OnFileChunk( char* FileChunk, int size );
void Init( wstring file, uint32_t size );
void SetLocalUserLocalPath( wstring path );
};
CFileTransferCS::CFileTransferCS( )
{
m_hFile = NULL;
m_wszLocalUserFolderPath = L"";
m_nChunkIndex = 0;
m_nWrittenBytes = 0;
}
CFileTransferCS::CFileTransferCS( wstring file, uint32_t size )
{
m_nChunkIndex = 0;
m_nWrittenBytes = 0;
m_wszfile = file;
m_nFileSize = size;
wstring wszFullFilePath = m_wszLocalUserFolderPath + m_wszfile.substr( m_wszfile.find_last_of(L"\\") + 1 );
// string fp = string( file.begin(),file.end() );
string fp ="test.bin"; //for testing purposes
this->m_hFile = fopen(fp.c_str(),"wb");
printf("fp: %s hFile %d\n",fp.c_str(),this->m_hFile); //everything's fine here...
if(!this->m_hFile)
{
perror ("cant open file ");
}
}
void CFileTransferCS::SetLocalUserLocalPath( wstring path )
{
m_wszLocalUserFolderPath = path;
}
void CFileTransferCS::Init( wstring file, uint32_t size )
{
// If previous transfer session got interrupted for whatever reason
// close and delete old file and open new one
if( this->m_hFile )
{
printf("init CS transfer: deleting old file///\n");
fclose( this->m_hFile );
string fp = string( file.begin(),file.end() );
if( remove( fp.c_str() ))
{
//cant delete file...
}
}
CFileTransferCS( file, size );
}
void CFileTransferCS::OnFileChunk( char* FileChunk, int size )
{
for (;;)
{
printf("ofc: hFile %d\n",this->m_hFile); //m_hFile is 0 here...
if( !this->m_hFile )
{
// m_pofFile->open("kurac.txt",fstream::out);
printf("file not opened!\n");
break;
}
int nBytesWritten = fwrite( FileChunk, 1, size, this->m_hFile );
if( !nBytesWritten )
{
perror("file write!!\n");
break;
}
m_nWrittenBytes+=size;
if( m_nWrittenBytes == m_nFileSize )
{
fclose( m_hFile );
printf("file uplaod transfer finished!!!\n");
}
break;
}
printf("CFileTransferCS::OnFileChunk size: %d m_nWrittenBytes: %d m_nFileSize: %d\n",size,m_nWrittenBytes,m_nFileSize);
}
最终编辑:
我明白了.. 显式调用 CFileTransferCS( wstring file, uint32_t size ) 构造函数出现问题.. 像这样显式调用构造函数导致其中的这个指针不是原始指针(那个 Init 函数正在使用)所以当我打开文件时从中并将句柄保存到m_hFile,我在其他对象中执行此操作(现在我不确定CFileTransferCS(..)是否为CFileTransferCS对象调用分配的内存,或者它随机损坏了内存的其他部分..将用IDA检查它稍后)
感谢大家和我的歉意。
问候,迈克——
【问题讨论】:
-
您确定这实际上是一个错误?请记住,如果函数成功,则
errno无效。例如。在情况 1 中,fopen确实 返回NULL?您能否还显示用于打开文件并检查错误的代码? -
什么操作系统?编译器?现有文件/新文件?你能创建一个小的可编译代码来演示这个问题吗?
-
@Bill im on Debian (amd64) 在编译时使用 c++0x 开关。我总是在调用 fopen/open 时创建新文件。
-
@Joachim Pileborg 我编辑了我的第一篇文章作为对你的回答。
-
我明白了.. 显式调用 CFileTransferCS( wstring file, uint32_t size ) 构造函数出现问题.. 像这样显式调用构造函数导致其中的这个指针不是原始指针(那个 Init 函数正在使用)所以当我从中打开文件并将句柄保存到 m_hFile 时,我在其他一些对象中执行此操作(现在我不确定 CFileTransferCS(..) 是否为 CFileTransferCS 对象调用分配的内存,或者它随机损坏了内存的其他部分......会稍后与 IDA 一起检查)谢谢大家,我很抱歉。问候,迈克