タイトルにあるように、バイナリ書き込み用にファイルを開こうとしているときにこのエラーが発生します(モードは問題ではないようです)。
私のアプリは libev を使用してソケット (非ブロッキング/epoll バックエンド) を処理し、クライアント パケットの解析中に、サーバーから取得したディスク データへの書き込みを開始するファイル アップロード メッセージを受信した時点で必要です。
メッセージとファイルを開くことについて何もグーグルできませんでしEAGAIN(Resource temporarily unavailable)
た..
これらは私が試した方法です:
- fopen( ... )が返す
EAGAIN
- ofstream/fstream のopen(...)を heap(new) の戻り値に作成して使用する
EAGAIN
- ofstream/fstream のopen(...)をクラス メンバー (
ofstream m_ofFile;
) として静的に使用することはできますが、奇妙なことに、コンパイラは ofstream デストラクタを呼び出してファイルを閉じてから、 .openを呼び出しているクラス メソッド im を終了するコードを生成します。クラスタイプであるクラスメンバーの場合、デストラクタはクラス所有者の直前に呼び出されるという私のC++の知識と矛盾しています..
編集:
@ヨアヒム
そうです、私はこのエラーを正確に受け取っていません..(メソッド#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 でチェックアウトします)
皆さんに感謝し、お詫び申し上げます。
よろしく、マイク–</p>