質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

2回答

3089閲覧

複数の端末から1つのファイルを操作するには

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

0クリップ

投稿2018/11/28 06:10

編集2018/11/28 07:58

visual studio2017、C#で
複数の端末からファイルサーバー上の1つのファイルを読み書きするプログラムを作りたいと考えています。

以下、質問の修正依頼があり、自分でもわかりにくい質問だったと思うので殆ど内容が変わっています。

実現したいこと

  • 複数のPCから1つのファイル(情報)の読込み、変更

ファイルの中身は1行で
01,0,1,0
02,0,0,1
.
.
.
19,0,1,0
のようなCSV形式になっており、[モノの番号,状態1,状態2,状態3]という具合です。
モノは1から19まであります。ファイルは19個あります。状態は1か0で表し、1の場合はオン、0の場合はオフです。
モノに対し3つのステータスがあり、それぞれのステータスのオン、オフがあります。

このファイルの情報をもとに画面上の[モノ]の見た目を変化させています。
たとえば、ファイル01の中身が[01,1,0,0]だった場合、画面上のモノ01のステータス1がオン、2がオフ、3がオフといった具合です。

この19個ファイルに対しての書込み、読込みを複数のPCから行いたいです。
書込みは状態1、2、3、の**[0か1か]**を書き換えるだけ。
読込みはファイルが書き換えられた時点で読込み、その情報をもとに画面上のモノの状態を変化させます。
前提として、ファイルが書き換えられた時点でファイルを読み込む必要があるので、FileSystemWatcherを使って19個のファイルを監視しています。

問題になっていること

問題1
ファイルの書き換えをした時点でFileSystemWatcherが働く。

FileSystemWatcherのイベントでファイルを読み込みに行くが、別のプロセスが使用中とエラーが発生する。
(おそらくですが、ファイルの書き換えがまだ終了していない。)

C#

1//sensor.csvファイルを指定された値に変更するメソッド 2 public void SensorSettingChange(string path,int to,string value) { 3 string filePath = ConfigurationManager.AppSettings["SensorPath"] + path; 4 string[] snInfo; 5 //csvファイル読込 6 try { 7 using (FileStream fsr = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 8 using (StreamReader sr = new StreamReader(fsr)) { 9 snInfo = sr.ReadLine().Split(','); 10 } 11 snInfo[to] = value; 12 //変更した値をcsvファイルに書込 13 using (FileStream fsw = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Write)) 14 using (StreamWriter sw = new StreamWriter(fsw)) { 15 sw.WriteLine(string.Join(",", snInfo)); 16 } 17 } catch { 18 //エラー通知 19 } 20 }

ファイル書き換えのメソッドです。
まず、書き換える前の状態を知るために一度書き換えるファイルを読み込み、配列に入れます。
そして引数をもとに、配列の中身を変更し、書き換えを行っています。

usingでストリームを閉じているはずなのですが、読込み時にエラーが発生する場合があります。
しかし、エラーが発生しない場合もあります。

問題2
ファイルの書き換えを複数のPCから同時に行う

別のプロセスが使用中とエラーが発生する。

こちらは先ほどの書き込みメソッドのCatch部分に”他の端末から操作している可能性があります。”とメッセージを表示しているのですが、できれば他の端末の処理が終わるまで自動で待ち、ファイルのアクセスが可能になった時点で操作を反映させたいと思っています。(ユーザーからそうして欲しいと依頼があったため)

自分でやってみた解決策

問題1に対して。。。
おそらく、FileSystemWatcherが反応した時点で書き込みのストリームが閉じられていないので、イベントが発生した時点でスレッドを50ミリ秒止めています。
こうすることでエラーは発生しなくなりました。
しかし、本当に書き込みのストリームが閉じられていないのが原因か分からない状況です。

問題2に対して。。。
書込みメソッドのcatchの部分でもう一度書き込みメソッドを呼び出し、成功するまで永久ループをさせています。
しかし、これではかなり危険だと思っていて何か他の方法がないかと探しています。

ここでデータベースを用いることで排他制御ができるのではないかと思い、修正前の質問に至ります。
データベース排他制御を使うことで問題2が解決できるのではないかと考えていますが、ファイルの情報量がかなり少ないですし、採用するほどのものなのかがわかりません。
また、データベースにしてしまうと、ファイル監視ができなくなるのではないかと思い悩んでいます。

この2つの問題を解決するにはどのような作りをすると良いと思いますか?
皆様のご意見を参考にいろいろ試したいと思っています。よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2018/11/28 06:20

正直、このような場でほんの少しの情報を元に手探りで全設計を終えられるものではないと思いますし、「プロセス」と聞いてハテナマークを浮かべ、なおかつ調べもしない人に作れるよう教えるのは大変困難です。恐らく解決しないと思いますので、プロにしかるべき経費を使って依頼した方がいいと思います。
退会済みユーザー

退会済みユーザー

2018/11/28 06:21

本質問は作りたいものに対してどのような方法で作るのが良いのか?という意図で質問しました。 リンクの質問はベストアンサーに選ばせていただきましたが、トリガーをもう一度起こしてもらう。リトライ処理の抜け方を変更することで解決しました。
Zuishin

2018/11/28 06:23

どのような方法が良いか考えるには詳しい情報が必要ですが、その情報をここで出せるとは思えません。
退会済みユーザー

退会済みユーザー

2018/11/28 06:24

お叱りのお言葉ありがとうございます。お言葉ですがここの質問、回答で全てを解決しようとは思っていません。あくまで1つの意見、ヒントとして捉えているつもりです。 申し訳ございませんが、私の質問が気に入らないようでしたら今後ご回答していただかなくて結構です。
Zuishin

2018/11/28 06:25

もう一度読んでみてください。どのような方法が良いか考えるには詳しい情報が必要ですが、その情報をここで出せるとは思えません。
Zuishin

2018/11/28 06:26

質問が気に入らないから叱られていると思っている時点であなたはこの質問が解決できません。
Zuishin

2018/11/28 06:28

情報の修正を求められるのが気に入らないなら質問していただかなくて結構です。
退会済みユーザー

退会済みユーザー

2018/11/28 06:29

回答のほうにもありますが、確かに質問の内容が伝わりにくいと自分でも思いまいした。なにを実現したいのかを考え直し、質問を修正するつもりです。
退会済みユーザー

退会済みユーザー

2018/11/28 06:35

すみません。質問の修正を求められているとは思いませんでした。修正が気に入らないわけではありません。先ほど回答のほうで質問をもっと詳しくしたほうが良いとの指摘がありましたので修正します。
Zuishin

2018/11/28 06:44

飛躍しました。修正を求めていませんでしたね。十分な修正は無理だからお金を払ってプロに丸投げするのがいいという提案でした。「提案がいやなら」と訂正します。修正されるということなので私からはこれ以上ありません。
kenshirou

2018/11/28 06:46 編集

読み書き対象のファイルは、どのようなものなのでしょうか?また、専用のアプリ(今回作成のもの)でないと編集は不可なのでしょうか?あと、各端末でのファイル読込に制限はないのでしょうか?
退会済みユーザー

退会済みユーザー

2018/11/28 07:59

修正依頼をくださった方々すみませんでした。質問を修正させていただきました。また不明な点がありましたらご指摘下さい。
kenshirou

2018/11/28 08:41

モノ毎に19個のファイルがあり、内容は状態1,状態2,状態3とのことですが、例えば同じファイルの「状態2」の情報を複数の人が同時期に編集する(したい)ようなことは運用上あるのでしょうか?
kenshirou

2018/11/28 08:43

あと、データベースにしてしまうと、ファイル監視ができなくなるのではないかと懸念されていますが、ファイル監視ができなくなると困る理由は何でしょうか?
退会済みユーザー

退会済みユーザー

2018/11/28 08:50

同一ファイルの同一状態を変更する。ということは十分にあり得ます。また、ファイル監視ができなくなると、ファイルが変更された時点でファイルの情報を読み込むイベントがなくなってしまうからです。
kenshirou

2018/11/29 02:54 編集

ファイル監視をしたい理由は、ファイル更新があった場合にその内容を各ユーザ側のアプリにも読み込ませる、ということでしょうか?あと、ユーザがファイルのデータを修正しようとする際、現在の情報はユーザは知り得るのでしょうか?(例えば、モノ1の状態2が現在OFFなのでONにしよう、ということなのか、それとも、モノ1の状態2の状況は分からないが、OFFだったらONに変更しよう、ということなのか)
退会済みユーザー

退会済みユーザー

2018/11/30 04:55

ファイル監視の理由はその通りです。ユーザーがファイルを変更するときは、モノの状態を知った上で変更をかけることを前提としています。
guest

回答2

0

まずは本来なにをしたいがためにそのようなことをしてるか、というのを提示しましょう

ファイルを作りたい?ならデータベース持ち出してる場合じゃないだろうし、データベースに登録してなにをするんだ?という話になるし。

投稿2018/11/28 06:14

y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/11/28 06:26

確かに、本来どういうことをしたいのか、とういう一番大事な部分が読み取れませんね。。 すみませんでした。もう一度よく考え、質問を修正します。 ありがとうございました。
guest

0

ベストアンサー

問題1についてですが、そもそも、以下のコードのcsvファイル書込時のFileStreamコンストラクタの第4引数は正しいのでしょうか?

C#

1 //変更した値をcsvファイルに書込 2 using (FileStream fsw = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Write))

FileShare.Writeだと、このファイルへの他からの書き込みは許可するが、読取は許可しないことになりますので、FileShare.Readにして読取を許可した方が良いのではないでしょうか?
これであれば、FileSystemWatcherのイベントが発生した時点では、読取は許可されているので、例外の発生なく、読取モードで変更後の内容を得られるかも知れません。

また、問題2については、私ならタイマーを使用してリトライさせます。
例外発生したら、タイマーをセットして、タイマーTickでリトライ。
安全のため、何回かリトライしてもダメだったらメッセージを出して中断する、という感じです。
タイマーのインターバルが1秒くらいがいいのか、0.5秒くらいがいいのか、は実用的な程度にすればよいと思います。

投稿2018/11/30 05:52

編集2018/11/30 05:59
kenshirou

総合スコア772

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/11/30 06:56

確かに、FileStreamの第4引数が間違っていました。Readにすることによってエラーがなくなりました。 問題2の複数からの書き込みですが、権限機能つけました。権限のフラグ管理も結局はファイルなのですが、ファイル内容が単純で、万が一競合が起き、ファイルが消えてしまってもユーザーの方で復旧できるので大丈夫。という内容でOKをいただきました。 ここまで詳しく掘り下げ、ご回答していただき本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問