在磁盘上创建/打开文件返回EAGAIN

时间:2012-09-09 15:24:40

标签: c++ file-io

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

我的应用程序使用libev来处理套接字(非阻塞/ epoll后端),并在解析客户端数据包时,我希望在某些时候我收到fileupload消息,开始写下我从服务器获取的磁盘数据。

我无法谷歌查询EAGAIN(Resource temporarily unavailable)消息和文件打开..

这些是我尝试过的方法:

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

    @Joachim

    你是对的,我并没有真正得到这个错误..(方法#1。很快会再次测试方法#2)。文件打开常规,我得到常规文件*。这发生在我的类的Init(...)函数中,但是当我稍后调用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文件,uint32_t大小)构造函数会产生问题。这样调用构造函数显式导致它中的这个指针不是原始的(Init函数正在使用)所以当我打开文件时从它和保存句柄到m_hFile,我在其他一些对象中做(现在我不确定CFileTransferCS(..)是否为CFileTransferCS对象调用了已分配的内存,或者它随机损坏了内存的其他部分...将使用IDA检查它稍后)

    感谢大家和我的道歉。

    问候,迈克 -

1 个答案:

答案 0 :(得分:0)

@MikeJacksons回答:

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

已删除:CFileTransferCS( file, size );

(不需要向迈克道歉,看起来你在搜寻错误方面做得很好)。