- PR -

2アプリによる同一ファイルの読み書き処理について

1
投稿者投稿内容
びぎな
常連さん
会議室デビュー日: 2005/03/02
投稿数: 25
投稿日時: 2005-04-05 11:03
いつもお世話になっております。
C#を使用して、アプリBの開発を行っております。

アプリA
アプリB
ファイルC
があります。

アプリAは、ファイルCへ書き込みを行います。
書き込みのタイミングはランダムで、こちら側から
制御はできません。(アプリAは既存の配布物なので、手は加えられません。)

一方アプリBは、ファイルCのコピーを同マシン上に行います。
ファイルCへの変更が発生した時点でコピーを行うか、定期的(5秒毎)にコピーが
行えれば問題ありません。
(FileSystemWatcherまたはTimerを使用)

コピー中に、アプリAによる書き込みが行われると、
アプリAがI/Oエラーにより、処理が落ちてしまいます。

今まで試した方法としましては、File.Copyを使用すると、I/Oエラー(103)
とういダイアログが出て、処理がとまります。

また、FileStreamを使用してファイル読取り→書き込みを行っても
同様にI/Oエラーが発生します。

****FileStream使用ソースの一部抜粋****
// Read the file.
using (FileStream fs = File.Open(CopyOrigin,FileMode.Open,FileAccess.Read,FileShare.ReadWrite))
{
byte[] b = new byte[fi.Length];
UTF8Encoding temp = new UTF8Encoding(true);
while(fs.Read(b,0,b.Length) > 0)
{
sData += temp.GetString(b);
}
}
// Write the file.
using (FileStream fs = File.OpenWrite(CopyDestination))
{
Byte[] info = new UTF8Encoding(true).GetBytes(sData);
fs.Write(info, 0, info.Length);
}

どなたか良い知恵をお貸し頂けますでしょうか?
よろしくお願い致します。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2005-04-05 11:44
引用:

どなたか良い知恵をお貸し頂けますでしょうか?



基本的にはどうしようもありません。
(言うことを聞く)アプリ A の代替物を用意するのが最善です

特に、アプリ A がファイル C を占有=オープンし続けているようなら、まったく望みはありません。
(排他オープンしていないとしても、ファイルの整合性は破壊されるでしょう)

もし、アプリA が定期的にファイル C に「触らない=オープンしていない」状況があるなら、非常に危うい方法ですが

・アプリ A をサスペンドする
・ファイル C を置き換える
・アプリ A をリジュームする

という手順で急場をしのげるかもしれません。(しないかもしれません)

_________________
// 渋木宏明 (Hiroaki SHIBUKI)
// http://hidori.jp/
// Microsoft MVP for Visual C#
//
// @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/
Gun
常連さん
会議室デビュー日: 2005/01/24
投稿数: 23
投稿日時: 2005-04-05 14:25
アプリAは他のシステムでどうしようもないのですよね。
で、アプリAを作るような時間も予算もないような状況、私もあります。

上記要件であれば、ファイルをコピーする前後にループとTry&Catchを書いて、IOエラーをキャッチしたら、リトライするとかいかがでしょうか?
あとリトライ回数を予めConstなどで指定しておいて、既定回数リトライしたらエラーログ、エラーメールを送り、ループを抜け出し終了とか。
あと、リトライする際に、
System.Threading.Thread.Sleep(1000)等を設定して、1秒後にもう一度チャレンジする、等の仕組みを書いてみるとか。

いかがでしょうか?
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2005-04-05 14:49
無理じゃない?

恐らくAアプリケーションは
1.他プロセスによる読書き禁止でファイルを開く
2.必要なファイルI/Oを行う
3.ファイル閉じる
と言う処理を定期的に繰り返しているのでしょう。1.でファイルを開くときに、他プロセスがファイルをコピーするために開いているとI/Oエラーとなるのでしょうね。ファイルをコピーしている以上、1.の処理でエラーになるのは避けられません。エラーが発生する事を前提として、Aアプリケーションを書き換えるのが王道でしょう。

Aアプリケーションを書き換える事が出来ないなら、1.が正常に終了するような方法でファイルのコピーを作るか、1.の処理が行われないようにAアプリケーションを停止しておく以外に方法はありません。とりあえず思いつくのはフィルタドライバ作るとか、シャドウボリュームコピーが作ったバックアップから取り出すとかかなぁ。

_________________
甕星 <mikahosi@abox9.so-net.ne.jp>
http://blogs.msmvp.jp/mikahosi/
Gun
常連さん
会議室デビュー日: 2005/01/24
投稿数: 23
投稿日時: 2005-04-05 15:32
びぎなさん、甕星さん、失礼しました。
コピー中にアプリAが落ちる、と言うことですね。
勘違いしておりました。失礼しました。

うーん、確かに難しそうですね。
何か代替手段がないか考えてみます。
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2005-04-05 16:40
参考
オープンファイル
例えば、Windows Server 2003では標準でVSS
と呼ばれるスナップショット機能が実装されています。
http://www.thinkit.co.jp/free/compare/5/3/1.html

びぎな
常連さん
会議室デビュー日: 2005/03/02
投稿数: 25
投稿日時: 2005-04-05 17:10
渋木宏明さん、Gunさん、甕星さん、MMXさん
ご返答ありがとうございます。
やはり、厳しそうですね・・

アプリAは他社からの配布物なので、全く触れない状況ですが、
恐らく甕星さんのおっしゃる様な仕様です。

環境はWindows2000Serverですが、
2003Serverのスナップショットのような機能が
2000Serverでも使えないか調べてみます。
1

スキルアップ/キャリアアップ(JOB@IT)