0

正如标题所说,我在尝试打开文件进行二进制写入时遇到此错误(模式似乎无关紧要)。

我的应用程序使用 libev 来处理套接字(非阻塞/epoll 后端),并且在解析客户端数据包时,我希望在某个点接收文件上传消息以开始将我从服务器获取的磁盘数据写入磁盘。

我无法在谷歌上搜索有关EAGAIN(Resource temporarily unavailable)消息和文件打开的任何内容..

这些是我尝试过的方法:

  1. fopen( ... )返回EAGAIN
  2. 通过在堆(新)返回上创建它们来使用 ofstream/fstream 的open(...)EAGAIN
  3. 静态使用 ofstream/fstream 的open(...)作为类成员 ( ofstream m_ofFile;) 可以工作,但是编译器会生成调用 ofstream 析构函数并在退出类方法之前关闭文件的代码 im 调用.open。现在这与我的 C++ 知识相矛盾,对于作为类类型的类成员,析构函数在类所有者之前被调用。

编辑:

@约阿希姆

你是对的,我并没有真正得到这个错误..(方法#1。很快就会再次测试方法#2)。文件定期打开,我得到常规文件*。这发生在我班级的 Init(...) 函数中,但是当我稍后在 m_hFile 为 0 时调用 OnFileChunk 时,因此我无法写入它。这是完整的类代码:

                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 进行检查)

谢谢大家和我的歉意。

问候,迈克——</p>

4

1 回答 1

0

@MikeJacksons 回答:

显式调用 CFileTransferCS(wstring file, uint32_t size) 构造函数会产生问题。像这样显式调用构造函数会导致其中的这个指针不是原始指针(Init 函数正在使用)所以当我从它打开文件并将句柄保存到 m_hFile 时,我在其他一些对象中执行它(现在我不确定是否 CFileTransferCS (..) 为 CFileTransferCS 对象调用分配的内存,或者它随机损坏了内存的其他部分.. 稍后将使用 IDA 检查它)谢谢大家和我的歉意。

删除:CFileTransferCS( file, size );

(无需向 Mike 道歉,看起来你在寻找错误方面做得很好)。

于 2013-09-18T10:26:27.833 回答