簡體   English   中英

在磁盤上創建/打開文件返回EAGAIN

[英]creating/opening file on disk returns EAGAIN

如標題所述,嘗試打開文件進行二進制寫入時出現此錯誤(模式似乎無關緊要)。

我的應用程序使用libev來處理套接字(非阻塞/ epoll后端),並且在解析客戶端數據包時,我希望在某個時候收到文件上傳消息,以便開始寫出從服務器獲取的磁盤數據。

我無法搜索有關EAGAIN(Resource temporarily unavailable)消息和文件打開的任何信息。

這些是我嘗試過的方法:

  1. fopen(...)返回EAGAIN
  2. 通過在堆(新)上創建它們來使用ofstream / fstream的open(... )返回EAGAIN
  3. 在類成員( ofstream m_ofFile; 靜態使用ofstream / fstream的open(...)可以正常工作,但是奇怪的是,編譯器會生成代碼,該代碼調用ofstream析構函數並關閉文件,然后退出類方法, .open中調用.open 現在,這與我的C ++知識相矛盾,對於類類型的類成員,析構函數在類所有者之前被調用。

編輯:

@Joachim

您是對的,我沒有發現這個錯誤..(方法#1。很快將再次測試方法#2)。 文件定期打開,我得到常規FILE *。 這發生在我類的Init(...)函數中,但是后來當我稍后在m_hFile上調用OnFileChunk時,它為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進行檢查)

感謝大家和我的歉意。

問候,邁克-

@MikeJacksons答案:

顯式調用CFileTransferCS(wstring file,uint32_t size)構造函數會出現問題。 像這樣顯式調用構造函數會導致其中的指針不是原始指針(Init函數正在使用的指針),因此當我從中打開文件並將句柄保存到m_hFile時,我正在其他對象中執行此操作(現在不知道是否CFileTransferCS (..)調用為CFileTransferCS對象分配的內存,否則它隨機破壞了內存的其他部分..稍后將使用IDA進行檢查)謝謝大家和我的歉意。

刪除: CFileTransferCS( file, size );

(無需向Mike表示歉意,看起來您在解決bug方面做得很好)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM