teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

1

質問内容の情報が少ないとのご指摘がありましたので修正しました。すみませんでした。

2018/11/28 07:58

投稿

退会済みユーザー
title CHANGED
File without changes
body CHANGED
@@ -1,29 +1,89 @@
1
1
  visual studio2017、C#で
2
2
  複数の端末からファイルサーバー上の1つのファイルを読み書きするプログラムを作りたいと考えています。
3
3
 
4
- **以下、実現したとの問題点です。**
4
+ 以下、質問の修正依頼があり、自分でもわかりにく質問だった思うので殆ど内容が変わっています。
5
5
 
6
+ **実現したいこと**
6
- 0. 複数のPCから1つのファイルに対して書き込みをする。
7
+ - 複数のPCから1つのファイル(情報)の読込み、変更
8
+ ファイルの中身は1行で
9
+ 01,0,1,0
10
+ 02,0,0,1
11
+ .
12
+ .
13
+ .
14
+ 19,0,1,0
7
-  →書き込み操作が重なったとき例外が発生ししまう。
15
+ のようCSV形式になっており、[モノの番号,状態1,状態2,状態3]とい具合です
8
-
9
- 1. ファイルが変更されたら各端末にその情報を反映する。
10
-  →FileSystemWatcherそれぞれのPCがファイルを監視るようにているがなんだか気持ちが悪い(他にいい方法がありそう)
16
+ モノは1から19まあります。ファイルは19個ありま。状態は1か0で表し、1の場合はオン、0の場合はオフです
17
+ モノに対し3つのステータスがあり、それぞれのステータスのオン、オフがあります。
11
18
 
12
- **解決策になりそうな案**
13
- - 1につてファイルサーバー上のtxtファイルではなく、データベース用い管理
19
+ このファイルの情報をもとに画面上の[モノ]の見た目変化させいます。
14
- データベースについての知識がほぼゼロで、開発経験もありません(入門書を1冊読んだ程度)が、データベースは排他制御ができるらしく、1の解決策になりそうかなと思っています。
15
- しかしデータベース化するほど情報量ではない(20行程度それぞれ20文字ずつ)で本当にデータベーにするののか分からない状況です。
20
+ たとえばファイル01中身が[01,1,0,0]だった場合、画面上モノ01のステータス1オン、2がオフ、3がオフとった具合です。
16
21
 
22
+ この19個ファイルに対しての書込み、読込みを複数のPCから行いたいです。
23
+ 書込みは状態1、2、3、の**[0か1か]**を書き換えるだけ。
24
+ 読込みはファイルが書き換えられた時点で読込み、その情報をもとに画面上のモノの状態を変化させます。
17
- - 2については全く案がない状態です。データベース化するFileSystemWatcherは使えないだろうし、以外にファイルの変更検知すが私にはわかりせん。。
25
+ **前提としファイルが書き換えらた時点でファイルを読み込む必要があるので、FileSystemWatcherを使って19個のファイルを監視してい**
18
26
 
19
- **サーバー?のようなものを作れば全て解決?**
20
- 私自身、サーバーと言われてもピンとこないくらい知識がないのですが、サーバーを立てることで1の排他制御、2のファイル変更の反映 、どちらも解決できるのでは?と思っています。
21
27
 
22
- ただ、よくわかっていないのは
28
+ **問題になっていること**
23
- ・サーバーを立てるので1台サーバー専用のPCが必要になる?
24
- ・サーバーが行うのは各端末の処理(本来端末がファイルを変更するが、ファイル変更そのものの処理をサーバーが代わりにしてくれる?)という考えで良いのか?
25
- ・ファイル変更の反映はどうするのか全く見当がつかない
26
- ということです。
27
29
 
30
+ 問題1
31
+ ファイルの書き換えをした時点でFileSystemWatcherが働く。
32
+
33
+ FileSystemWatcherのイベントでファイルを読み込みに行くが、別のプロセスが使用中とエラーが発生する。
34
+ (おそらくですが、ファイルの書き換えがまだ終了していない。)
35
+
36
+ ```C#
37
+ //sensor.csvファイルを指定された値に変更するメソッド
38
+ public void SensorSettingChange(string path,int to,string value) {
39
+ string filePath = ConfigurationManager.AppSettings["SensorPath"] + path;
40
+ string[] snInfo;
41
+ //csvファイル読込
42
+ try {
43
+ using (FileStream fsr = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
44
+ using (StreamReader sr = new StreamReader(fsr)) {
45
+ snInfo = sr.ReadLine().Split(',');
46
+ }
47
+ snInfo[to] = value;
48
+ //変更した値をcsvファイルに書込
49
+ using (FileStream fsw = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Write))
50
+ using (StreamWriter sw = new StreamWriter(fsw)) {
51
+ sw.WriteLine(string.Join(",", snInfo));
52
+ }
53
+ } catch {
54
+ //エラー通知
55
+ }
56
+ }
57
+ ```
58
+
59
+ ファイル書き換えのメソッドです。
60
+ まず、書き換える前の状態を知るために一度書き換えるファイルを読み込み、配列に入れます。
61
+ そして引数をもとに、配列の中身を変更し、書き換えを行っています。
62
+
63
+ usingでストリームを閉じているはずなのですが、読込み時にエラーが発生する場合があります。
64
+ しかし、エラーが発生しない場合もあります。
65
+
66
+ 問題2
67
+ ファイルの書き換えを複数のPCから同時に行う
68
+
69
+ 別のプロセスが使用中とエラーが発生する。
70
+
71
+ こちらは先ほどの書き込みメソッドのCatch部分に”他の端末から操作している可能性があります。”とメッセージを表示しているのですが、できれば他の端末の処理が終わるまで自動で待ち、ファイルのアクセスが可能になった時点で操作を反映させたいと思っています。(ユーザーからそうして欲しいと依頼があったため)
72
+
73
+ **自分でやってみた解決策**
74
+
28
- 知識足らずですみません。。。
75
+ 問題1に対して。。。
76
+ おそらく、FileSystemWatcherが反応した時点で書き込みのストリームが閉じられていないので、イベントが発生した時点でスレッドを50ミリ秒止めています。
29
- か皆様のご意見を聞かせてださい
77
+ することでエラーは発生しななりました
78
+ しかし、本当に書き込みのストリームが閉じられていないのが原因か分からない状況です。
79
+
80
+ 問題2に対して。。。
81
+ 書込みメソッドのcatchの部分でもう一度書き込みメソッドを呼び出し、成功するまで永久ループをさせています。
82
+ しかし、これではかなり危険だと思っていて何か他の方法がないかと探しています。
83
+
84
+ ここでデータベースを用いることで排他制御ができるのではないかと思い、修正前の質問に至ります。
85
+ データベース排他制御を使うことで問題2が解決できるのではないかと考えていますが、ファイルの情報量がかなり少ないですし、採用するほどのものなのかがわかりません。
86
+ また、データベースにしてしまうと、ファイル監視ができなくなるのではないかと思い悩んでいます。
87
+
88
+ この2つの問題を解決するにはどのような作りをすると良いと思いますか?
89
+ 皆様のご意見を参考にいろいろ試したいと思っています。よろしくお願いします。