
CFile::Renameで書き込み途中のファイルがリネームされて困っています。
ファイル書き込み中のファイルはリネームしない方法はあるのでしょうか?
ファイルのリネーム(CFile::Rename)関数を使用してフォルダ内にあるファイル名をリネームする処理を作成しています。
フォルダ内にはA_で始まるファイルが複数存在し、一定周期で別のスレッドからA_で始まるファイルが書き込まれている状態です。
私が作成している処理は、そのフォルダにA_で始まるファイルが存在する場合に、A_をRename関数でB_にリネームしています。
ここで、別スレッドがA_で始まる新しいファイルを書き込みしている最中に私が作成している処理でRename関数が実行されると、基本的にはExceptionが発生するのですが、Exceptionが発生せずに書き込み途中のファイルがRenameされてしまっています。
1.A_XXX001.txtに書き込み中(100行目まで書き込み完了)
2.Rename処理が実行される。
3.B_XXX001.txtが作成される(100行目までのファイル 作成日:2010.02.04 10:00)
4.その後もA_XXX001.txtに書き込みが行われ200行目まで書き込んで終了
(作成日:2010.02.04 10:02)
結果:B_XXX001.txtファイルは不完全なファイルとして作成されてしまっています。
このような現象が起こってしまっています。
どなたかご教授願います。
A 回答 (5件)
- 最新から表示
- 回答順に表示
No.5
- 回答日時:
もう見てないかもしれませんが・・・
Mutex等で排他制御をする場合、排他にしたい操作全部にロック操作を追加します。今回の場合だとファイル書き込みとファイル名変更ですね。参考ソースがあるのでそこに追記してみました。
CMutex mtxFile; // このオブジェクトをファイル名変更ロジックからもアクセスできるようにしておく
CStdioFile csfCsvFile;
CFileException e = NULL;
CSingleLock lockFile(&mtxFile);
lockFile.Lock();
csfCsvFile.Open(csFullPath,CFile::modeCreate | CFile::modeWrite | CFile::typeText,&e)
try {
pos = NULL;
if ( !csCsvDataList.IsEmpty() ) pos = csCsvDataList.GetHeadPosition();
while ( pos != NULL ) {
CString csCsvRecord;
csCsvRecord = "書き込み内容";
// 1行書込の実行
csfCsvFile.WriteString(csCsvRecord);
csfCsvFile.WriteString(_T("\n"));
}
}
// ファイル書き込み失敗時
catch ( CFileException *e ) {
エラーログ出力
}
lockFile.Unlock();
これと同じようにしてファイル名変更ロジックにLock~Unlockを追加します。
ただし、この場合だと1行書き込んだタイミングでロックが解除されますので、全部書き込むまでロックする場合は、そのロジック全体をLock~Unlockで囲う必要があります。

No.4
- 回答日時:
書き込み側のスレッドで、A_XXX001.TXTのファイル名でいきなり書くのでなく、
TEMP_XXXのようなファイル名で書いて、書き込み完了後、そのスレッドが、A_XXX001.TXTのファイル名にリネームにしてはいかがでしょうか。
(パフォーマンス等は、考慮していません。)
No.2
- 回答日時:
ある資源(今回の場合はファイル)に対して複数のスレッドからアクセスするシステムの場合、クリティカルセクションなりセマフォなりを利用して複数のスレッドが同じ資源に同時にアクセスしないようにするのが常識です。
開発環境がわかりませんので、マルチスレッド等のキーワードでググってください。
No.1
- 回答日時:
MutexかEventを使って排他制御するのが一番だと思いますが・・・
この回答への補足
MISTMOON79 さん、RESET_CAT さん ありがとうございます。
現在、排他制御に関して調べているのですが、今回の私の処理の場合、
排他制御を掛けるのはファイル書き込みの部分に当たるのでしょうか?
書き込みをしているファイルを排他制御対象にすることで、そのファイル名を変更するRenameはロックされているファイルはRenameしなくなるのでしょうか?
現在、書き込み処理は以下のようになっています。
Mutexを使用する場合はどのようにしたら、書き込んでいるファイルをロックできるのでしょうか?
CStdioFile csfCsvFile;
CFileException e = NULL;
csfCsvFile.Open(csFullPath,CFile::modeCreate | CFile::modeWrite | CFile::typeText,&e)
try {
pos = NULL;
if ( !csCsvDataList.IsEmpty() ) pos = csCsvDataList.GetHeadPosition();
while ( pos != NULL ) {
CString csCsvRecord;
csCsvRecord = "書き込み内容";
// 1行書込の実行
csfCsvFile.WriteString(csCsvRecord);
csfCsvFile.WriteString(_T("\n"));
}
}
// ファイル書き込み失敗時
catch ( CFileException *e ) {
エラーログ出力
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
USBメモリが接続されているか確...
-
.NETアプリを作ったときの .man...
-
コマンドプロンプトで作成日時...
-
Latexで図番号だけを「図1.1」...
-
Batファイルをバイナリ形式にす...
-
VBAのバイナリ出力について
-
5ちゃんねるに画像を投稿した...
-
アクセス 壊れた? 「ファイ...
-
binファイルを解凍したいの...
-
ダウンロードしたファイルがind...
-
公文書のxmlファイルの開き方が...
-
C言語でクイズゲームを作らな...
-
ffftpでアップすると文字化けを...
-
エクセルのVBAについて とある...
-
ftpコマンドを実行すると「425 ...
-
コマンドプロンプトのエラーに...
-
win10の「フォト」で、「次へ」...
-
大量のフォルダからひとつのフ...
-
一括でフォルダと同じ名前にフ...
-
コマンドプロンプトの「%1」と...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「営業秘密の漏洩」について
-
アクセス 壊れた? 「ファイ...
-
#include <Windows.h>というヘ...
-
.NETアプリを作ったときの .man...
-
Latexで図番号だけを「図1.1」...
-
コマンドプロンプトで作成日時...
-
公文書のxmlファイルの開き方が...
-
jarファイル
-
リンクの張り付けかたを教えて...
-
binファイルを解凍したいの...
-
監視ツールを入れさせられまし...
-
自分で作成した重要ファイルを...
-
「ブルーファイル」と「グリー...
-
C言語---ファイルに出力したデ...
-
Seasar2のdiconファイルの読み方
-
コマンドプロンプトで、指定し...
-
バッチ処理で追記コピーしたい
-
C#でログファイルにファイルパ...
-
ファイルが開かれているかどう...
-
HTAのウィンドウを閉じるには・...
おすすめ情報