C言語でのファイル書き込みと読み込み不都合
C言語でのファイル書き込みと読み込み不都合
MS VCでファイルの書き込み文を実行直後、すぐ読み込みをすると、
前回書き込んだファイルのデータが読み込んでしましました。
(直前の書き込みが途中であるためか)
これまで自分の想像ではC言語の関数が書き込んでから、はじめて次の文に行くとしましたが、実際そうでないと実証しました。
さて、どうすれば、直前の書き込み完成してから、直後の読み込みを実行することができるのでしょうか。
今直前の書き込みの直後にSleep()を取っています。
ただし、sleepの時間が短すぎだと、効かないし、長すぎると時間的にもったいない。
良い方法があれば、是非教えてください!
前回書き込んだファイルのデータが読み込んでしましました。
(直前の書き込みが途中であるためか)
これまで自分の想像ではC言語の関数が書き込んでから、はじめて次の文に行くとしましたが、実際そうでないと実証しました。
さて、どうすれば、直前の書き込み完成してから、直後の読み込みを実行することができるのでしょうか。
今直前の書き込みの直後にSleep()を取っています。
ただし、sleepの時間が短すぎだと、効かないし、長すぎると時間的にもったいない。
良い方法があれば、是非教えてください!
Re: C言語でのファイル書き込みと読み込み不都合
うまくいかないというプログラムを載せてください。
(file closeしてないとか?)
(file closeしてないとか?)
Re: C言語でのファイル書き込みと読み込み不都合
fflush関数を用いると、ファイルへの書き込みを完了させることができます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: C言語でのファイル書き込みと読み込み不都合
その実証が間違っていないことを実証してください。ABA さんが書きました: これまで自分の想像ではC言語の関数が書き込んでから、はじめて次の文に行くとしましたが、実際そうでないと実証しました。
ABA さんが書きました: さて、どうすれば、直前の書き込み完成してから、直後の読み込みを実行することができるのでしょうか。
#include <stdio.h>
int main(void)
{
char buf[1024];
FILE *fin, *fout;
fout = fopen("a.txt", "w");
if (fout == NULL) { puts("can't create b.txt"); return 2; }
fin = fopen("a.txt", "r");
if (fin == NULL) { puts("can't open a.txt"); return 1; }
fputs("abcdefg\n", fout); // または fprintf(fout, "abcdefg\n");
fflush(fout); // これがあるとないとで大違い
if (fgets(buf, sizeof buf, fin) != NULL)
fputs(buf, stdout);
else
printf("can't read a line\n");
fclose(fout);
fclose(fin);
return 0;
}
文字列書き込み fputs、
1文字書き込み fputc、
指定バイト数書き込み fwrite、
これらは、バッファリングしているバッファへの書き込みであり、
実際のファイルへの書き込みは、バッファがいっぱいになった時に
自動的に行われます。
したがって、書き込んだつもりでも、ファイルに本当に書き込みが
完了しているとは限りません。
fflush があると、バッファリングしているデータをすべてファイルに
書き込みます。
fclose もバッファリングしているデータをすべてファイルに書き
込んでから、ファイルをクローズします。
Re: C言語でのファイル書き込みと読み込み不都合
皆様
いろいろアイディア心より感謝致します。
再度fopen()や繰り返しfclose fflush(NULL)いろいろさんざんに試しましたが、
やはり、読み込みが可笑しいーーー直前のファイル内容でなく、もう一つ前の内容みたいですね。
実例: また宜しくお願い致します。
いろいろアイディア心より感謝致します。
再度fopen()や繰り返しfclose fflush(NULL)いろいろさんざんに試しましたが、
やはり、読み込みが可笑しいーーー直前のファイル内容でなく、もう一つ前の内容みたいですね。
実例: また宜しくお願い致します。
Re: C言語でのファイル書き込みと読み込み不都合
これは「C言語でのファイルの書き込み」ではありません。
最初から間違った情報を出して質問しても、適切な回答は得られませんよ。
「OpenCV の C++ でのファイルの書き込み」となぜ書かなかったのですか?
cv::imwrite の返却値が true か false かを調べてください。
m1 が壊れているかなんかで、imwrite がファイルを作成できないことが
考えられます。試しに、imageFileName のファイルを削除してから、
実行するとどうなりますか?
imwrite がファイルを作成しないと、fopen も失敗するはずです。
古いデータはありません。
Re: C言語でのファイル書き込みと読み込み不都合
かずま様
お返答ありがとうございます。
cv::imwrite(imageFileName, m1);// Mat m1.
自体が問題ないと考えられます。
その後のfopen()がきちんとできますし、
imwriteから返した値がempty()にならなかったのです。
なんといっても、このトッピを出した時に申し上げたように、
cv::imwrite(imageFileName, m1);// Mat m1.
の後ろに
Sleep(1000);
を置けば、以降まったく正常な画像データを読み込めます。
どう理解すれば良いのでしょうか。
お返答ありがとうございます。
cv::imwrite(imageFileName, m1);// Mat m1.
自体が問題ないと考えられます。
その後のfopen()がきちんとできますし、
imwriteから返した値がempty()にならなかったのです。
なんといっても、このトッピを出した時に申し上げたように、
cv::imwrite(imageFileName, m1);// Mat m1.
の後ろに
Sleep(1000);
を置けば、以降まったく正常な画像データを読み込めます。
どう理解すれば良いのでしょうか。
Re: C言語でのファイル書き込みと読み込み不都合
可能性の1つですが、
imwriteによる書き込み後直ちにfopenでファイルを開こうとした際、ディスク上のファイル(データ)をオープンする。
→imwriteで書き込んだデータはまだキャッシュ上からフラッシュされていないため古いデータが読み込まれる。
Sleepを入れることで正常なデータが読み込まれたのは、単に時間経過でメモリ上のデータがフラッシュされただけとか。
という動きをしているのであれば、バッファキャッシュやディスクキャッシュによる影響が考えられます。ABA さんが書きました: cv::imwrite(imageFileName, m1);// Mat m1.
の後ろに
Sleep(1000);
を置けば、以降まったく正常な画像データを読み込めます。
imwriteによる書き込み後直ちにfopenでファイルを開こうとした際、ディスク上のファイル(データ)をオープンする。
→imwriteで書き込んだデータはまだキャッシュ上からフラッシュされていないため古いデータが読み込まれる。
Sleepを入れることで正常なデータが読み込まれたのは、単に時間経過でメモリ上のデータがフラッシュされただけとか。
Re: C言語でのファイル書き込みと読み込み不都合
具体実例コーダまで書いていただいた方に本当に感謝の気持ちいっぱいです。
原因の推測はともかくとして、これまでファイル書き込みと読み込みの間、
Sleep関数を入れなければならないという経験がないし、聞いた事もないですね。
そのSleep関数の時間が気になります。
回避方法があれば、いつでもお教えいただければ幸いです。
[[未解決]]
原因の推測はともかくとして、これまでファイル書き込みと読み込みの間、
Sleep関数を入れなければならないという経験がないし、聞いた事もないですね。
そのSleep関数の時間が気になります。
回避方法があれば、いつでもお教えいただければ幸いです。
[[未解決]]
Re: C言語でのファイル書き込みと読み込み不都合
OpenCVの知識は全くないので直接的な回答はできませんが。
対処法はimwriteによる書き込み後にバッファキャッシュをフラッシュする、またはimwriteによる書き込みを
ダイレクトアクセス(バッファキャッシュを使用せずに書き込む)とすればよいと思いますが、その方法がわかりません、申し訳ありません。
そもそも書き込み直後にファイルをオープンするという処理もどうなのかなぁとも思いますが。
キャッシュが絡む話としては特に珍しくないように思います。ABA さんが書きました: 原因の推測はともかくとして、これまでファイル書き込みと読み込みの間、
Sleep関数を入れなければならないという経験がないし、聞いた事もないですね。
対処法はimwriteによる書き込み後にバッファキャッシュをフラッシュする、またはimwriteによる書き込みを
ダイレクトアクセス(バッファキャッシュを使用せずに書き込む)とすればよいと思いますが、その方法がわかりません、申し訳ありません。
そもそも書き込み直後にファイルをオープンするという処理もどうなのかなぁとも思いますが。
Re: C言語でのファイル書き込みと読み込み不都合
確かに imwrite が完了したときにはファイルをクローズしているはずなので、おかしいですね。
Sleep を使っているということは Windows だと思いますが、具体的な実行環境は何でしょうか。
また、 imageFileName で書き込んでいるファイル名・拡張子(画像形式)と、書き込み先の場所(ドライブ・種類など)は何ですか。
あと、アンチウィルスソフトなどは使っていますか。
Sleep を使っているということは Windows だと思いますが、具体的な実行環境は何でしょうか。
また、 imageFileName で書き込んでいるファイル名・拡張子(画像形式)と、書き込み先の場所(ドライブ・種類など)は何ですか。
あと、アンチウィルスソフトなどは使っていますか。
Re: C言語でのファイル書き込みと読み込み不都合
imwrite がやっていることは、C言語の標準ライブラリ関数を使用してバイナリ形式でファイルを開いて書き込んでファイルを閉じているだけです。
バージョンの記載が無いので、3.2 を対象とします。
imwrite は fopen(..., "wb") でファイルを開き、関数を終了する前に fclose でファイルを閉じます。
戻り値の型は bool です。fopen(..., "wb") に失敗した場合 false を返します。それ以外はtrueを返します。
imwrite は、独自でバッファリングしながら以下のタイミングで fwrite を実行します。
fwrite を実行する WBaseStream::writeBlock を呼び出すタイミングは以下の2パターンです。
1.fopen(..., "wb") が成功した状態(m_is_opened が true)で、fclose を実行する WBaseStream::close を呼び出したとき
2.バッファに書き込まれたデータサイズが BS_DEF_BLOCK_SIZE (1<<15) 以上になったとき
このとき、バッファに書き込まれたデータサイズが 0 でなければ fwrite が実行されます。
imwrite は fclose の戻り値を確認してません。(fclose が成功しても失敗しても ファイルディスクリプタを保持している変数に 0 を代入し、imwrite は true を返します)
fclose の失敗を考慮するなら、WBaseStream::close() で実行されているので、確認用のコードを追記して観測するのも手です。
(むしろ、何か事象が発生していればイベントビューアで ETW による書き込みを確認できるので、もし問題が発生していれば何が起きているかを知ることができます)
とりあえず、
確認せずに自論で結果を決めてしまったり、自分しか観測していない状況証拠だけで他者に結論を求めてみたり、話が浮ついていて要領を得ていないので、再現性があり誰でも事象を観測できる動作可能なコードをまずは載せてみてください。
その上で質問された方が早期に解決できるのではないかと思います。
バージョンの記載が無いので、3.2 を対象とします。
imwrite は fopen(..., "wb") でファイルを開き、関数を終了する前に fclose でファイルを閉じます。
戻り値の型は bool です。fopen(..., "wb") に失敗した場合 false を返します。それ以外はtrueを返します。
imwrite は、独自でバッファリングしながら以下のタイミングで fwrite を実行します。
fwrite を実行する WBaseStream::writeBlock を呼び出すタイミングは以下の2パターンです。
1.fopen(..., "wb") が成功した状態(m_is_opened が true)で、fclose を実行する WBaseStream::close を呼び出したとき
2.バッファに書き込まれたデータサイズが BS_DEF_BLOCK_SIZE (1<<15) 以上になったとき
このとき、バッファに書き込まれたデータサイズが 0 でなければ fwrite が実行されます。
imwrite は fclose の戻り値を確認してません。(fclose が成功しても失敗しても ファイルディスクリプタを保持している変数に 0 を代入し、imwrite は true を返します)
fclose の失敗を考慮するなら、WBaseStream::close() で実行されているので、確認用のコードを追記して観測するのも手です。
(むしろ、何か事象が発生していればイベントビューアで ETW による書き込みを確認できるので、もし問題が発生していれば何が起きているかを知ることができます)
とりあえず、
確認せずに自論で結果を決めてしまったり、自分しか観測していない状況証拠だけで他者に結論を求めてみたり、話が浮ついていて要領を得ていないので、再現性があり誰でも事象を観測できる動作可能なコードをまずは載せてみてください。
その上で質問された方が早期に解決できるのではないかと思います。
Re: C言語でのファイル書き込みと読み込み不都合
オフトピック
気づかれた方もいらっしゃるかもしれませんが、大筋は同じなので説明は1つのEncoderに絞ってあります。
最初にfcloseの動作から疑うのは定理を疑うようなもので手順としては少しナンセンスなので、特定環境のみなのか、特定Encoderのみなのか、特定ファイルのみなのか、などいくつか先に切り分けしておいた方が良いと考えます。
最初にfcloseの動作から疑うのは定理を疑うようなもので手順としては少しナンセンスなので、特定環境のみなのか、特定Encoderのみなのか、特定ファイルのみなのか、などいくつか先に切り分けしておいた方が良いと考えます。
Re: C言語でのファイル書き込みと読み込み不都合
sleep様
情報ありがとうございます。
自分はなぜかdebug状態でも
imwrite()関数の中身にジャンプできなかったんです。
ご提供の情報に基づいて、さらに確認します。
成果あればご報告させていただきます。
=========
追加情報
OS Windows10
環境 Visualstudio2015
Sleep() windowsのものです。
情報ありがとうございます。
自分はなぜかdebug状態でも
imwrite()関数の中身にジャンプできなかったんです。
ご提供の情報に基づいて、さらに確認します。
成果あればご報告させていただきます。
=========
追加情報
OS Windows10
環境 Visualstudio2015
Sleep() windowsのものです。