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

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

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

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

.NET Framework 4.0

Microsoft Windows用のソフトウェア開発環境/実行環境である .NET Frameworkの4番目のメジャーバージョンです。

Q&A

解決済

3回答

3863閲覧

c#におけるFileStreamの記述について

Kashi_wamochi

総合スコア14

C#

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

.NET Framework 4.0

Microsoft Windows用のソフトウェア開発環境/実行環境である .NET Frameworkの4番目のメジャーバージョンです。

0グッド

0クリップ

投稿2019/07/01 13:15

編集2019/07/02 00:17

前提・実現したいこと

Windows XPや Windows10上において計測プログラムがログを出しながら動いており、
そのログを用いて1秒間隔でグラフを描画したいと考えております。

発生している問題・エラーメッセージ

ただ、そのログを作成しているプログラム上から参照しようとすると、OpenFileDialogを開き、選択ボタンを押した段階で「別のプロセスが使用している」とのエラーが出ます。
拙いコードなのは重々承知なのですが、間違えている点はどのあたりにあるのでしょうか??
あるいはほかに良い方法があるのでしょうか??

もしよろしければ、ご教授お願いしたいです。
よろしくお願いいたします。

該当のソースコード

c#

1using System; 2using System.Collections.Generic; 3using System.ComponentModel; 4using System.Data; 5using System.Drawing; 6using System.Linq; 7using System.Text; 8using System.IO; 9using System.Timers; 10using System.Windows.Forms; 11using System.Windows.Forms.DataVisualization.Charting; 12 13namespace DigitShowBasic_Monitor 14{ 15 public partial class Form1 : Form 16 { 17 String FilePass; 18 String[] InitialCol; 19 private int XColNum; 20 private int YColNum; 21 22 public Form1() 23 { 24 InitializeComponent(); 25 XMax_NUD.Value = 100; 26 XMin_NUD.Value = 0; 27 YMax_NUD.Value = 10; 28 YMin_NUD.Value = -10; 29 30 31 32 } 33 34 private void FileChange_Button_Click(object sender, EventArgs e) 35 { 36 OpenFileDialog ofDialog = new OpenFileDialog(); 37 ofDialog.InitialDirectory = @"C:"; 38 ofDialog.Title = "Select output file"; 39 ofDialog.Filter = "Output Files (*.dat, *.out, *.vlt)|*.dat;*.out;*.vlt"; 40 ofDialog.RestoreDirectory = true; 41 42 43 if (ofDialog.ShowDialog() == DialogResult.OK ) 44 { 45 FilePass = ofDialog.FileName; 46 FileName.Text = ofDialog.SafeFileName; 47 } 48 ofDialog.Dispose(); 49 50 if (FilePass != null) 51 { 52 Update_ChartControls(); 53 } 54 55 } 56 57 private void Update_ChartControls() 58 { 59 FileStream fs = new FileStream(FilePass, FileMode.Open, FileAccess.Read, FileShare.Read); 60 StreamReader sr = new StreamReader(fs); 61 InitialCol = sr.ReadLine().Split(); 62 XAxis_Combo.Items.Clear(); 63 YAxis_Combo.Items.Clear(); 64 65 sr.Close(); 66 67 for (int i = 0; i < InitialCol.Count() - 1; i++) 68 { 69 XAxis_Combo.Items.Add(InitialCol[i]); 70 YAxis_Combo.Items.Add(InitialCol[i]); 71 } 72 XAxis_Combo.SelectedIndex = 0; 73 YAxis_Combo.SelectedIndex = 1; 74 } 75 76 private void StartDrawing_button1_Click(object sender, EventArgs e) 77 { 78 if (FilePass != null) 79 { 80 timer1.Start(); 81 } 82 } 83 84 private void timer1_Tick(object sender, EventArgs e) 85 { 86 chart1.Series.Clear(); 87 chart1.ChartAreas.Clear(); 88 89 Series seriesLine = new Series(); 90 seriesLine.ChartType = SeriesChartType.Line; 91 92 FileStream fs = new FileStream(FilePass, FileMode.Open, FileAccess.Read, FileShare.Read); 93 StreamReader sr = new StreamReader(fs, Encoding.UTF8); 94 95 string[] Data = new string[0]; 96 97 int j = 1; 98 while (sr.Peek() > -1) 99 { 100 Array.Resize(ref Data, j + 1); 101 Data[j] = sr.ReadLine(); 102 j++; 103 } 104 105 sr.Close(); 106 107 int NumLines = Data.Length; 108 var Step = 1; 109 110 XColNum = XAxis_Combo.SelectedIndex; 111 YColNum = YAxis_Combo.SelectedIndex; 112 113 if (NumLines >= 2000) 114 { 115 Step = NumLines / 1000; 116 117 } 118 else 119 { 120 Step = 1; 121 } 122 123 for (int i = 2; i < NumLines; i += Step) 124 { 125 var x = float.Parse(Data[i].Split()[XColNum]); 126 var y = float.Parse(Data[i].Split()[YColNum]); 127 DataPoint dp = new DataPoint((double)x, y); 128 seriesLine.Points.Add(dp); 129 } 130 ChartArea ChartArea1 = new ChartArea(); 131 132 chart1.ChartAreas.Add(ChartArea1); 133 chart1.Series.Add(seriesLine); 134 135 ChartArea1.AxisX.Maximum = (double)XMax_NUD.Value; 136 ChartArea1.AxisX.Minimum = (double)XMin_NUD.Value; 137 ChartArea1.AxisY.Maximum = (double)YMax_NUD.Value; 138 ChartArea1.AxisY.Minimum = (double)YMin_NUD.Value; 139 } 140 141 private void Button2_Click(object sender, EventArgs e) 142 { 143 timer1.Stop(); 144 } 145 } 146} 147

試したこと

こちらの方法を試して、上記のようにFileStreamの引数を変えてみましたが、同じエラーが発生します。
またこちらの方の記述を見ると、FileStreamの引数は少なくてもいいように思われます。

補足情報(FW/ツールのバージョンなど)

Visual Studio 2019 .Net Framework 4.0 c#

追記

ログを作成するプログラムは以下のようになっていました。

c++

1fopen_s(&FileSaveData1, (LPCSTR)pFileName1 , "w" ); 2fprintf(FileSaveData1,"%s ","Time(s)");

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

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

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

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

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

guest

回答3

0

そのログを作成しているプログラム上から参照しよう

ログ作成の方のコードはどうなっているでしょうか? そちらが、オープンしたままだと、読む方での対応ではどうしようもありません。

FileStream Class (日本語、怪しいですが) にFileStream の記述がありますが、機能が多すぎて覚えきれないですね。

投稿2019/07/01 14:06

pepperleaf

総合スコア6383

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

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

Kashi_wamochi

2019/07/02 00:03

>pepperleafさん 回答ありがとうございます。ログの方のプログラムの方を確認してみます。
pepperleaf

2019/07/02 12:12

"w"で openしているという事は、上書きですね。 同じプログラム内という事なら、わざわざ、ファイルから、読まずに、プログラム内で、データを置いて、それを使いまわした方が早いと思いますが、、。 また、ログファイルと言うと、実行中でも参照できるように、書込みしたら、すぐにクローズする等しないと、他から、参照できません。 (その時は、"w" じゃなくて、"a"オープンですね)
guest

0

ベストアンサー

FileShare.ReadWriteを指定しても読み込めないのであれば、書き込む側を変更するしかないかと思います。

ログの出力側でfopen_sで開いているとのことですが、こちら

Files that are opened by fopen_s and _wfopen_s are not sharable. If you require that a file be sharable, use _fsopen, _wfsopen with the appropriate sharing mode constant—for example, _SH_DENYNO for read/write sharing.

とあります。(日本語訳があやしいので、原文で引用しました)
簡単に言うとfopen_fで開いたファイルは共有できないので、共有したい場合は_fsopenを使いましょうとのことです。

fprintfで書き込んでも即時にファイルに反映されないので、必要に応じてfflushするなりしてください。

投稿2019/07/01 13:51

編集2019/07/02 01:29
YAmaGNZ

総合スコア10258

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

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

Kashi_wamochi

2019/07/02 00:02

>YAmaGNZさん 回答ありがとうございます。他の既成ソフトで開こうとしても同じメッセージが出たため、ご指摘の通りかなと思います...
Kashi_wamochi

2019/07/02 00:22

確認したところC++で書かれていました。 一応上記に該当すると思われる箇所のコードを添付しました。
guest

0

FileStream(だけでなくIDisposable実装してるクラスなら一般的に)使ったらDisposeするなりusingブロック使うなりしないとダメな気が。


追記
とりあえず

Diff

1- FileStream fs = new FileStream(FilePass, FileMode.Open, FileAccess.Read, FileShare.Read); 2- StreamReader sr = new StreamReader(fs); 3+ using(FileStream fs = new FileStream(FilePass, FileMode.Open, FileAccess.Read, FileShare.Read)) 4+ using(StreamReader sr = new StreamReader(fs)) { 5 InitialCol = sr.ReadLine().Split(); 6+ } 7 XAxis_Combo.Items.Clear(); 8 YAxis_Combo.Items.Clear(); 9 10- sr.Close();

こんな感じで。(もう一箇所も)

あと、どうでもいいですけどFilePassFilePathでは。

投稿2019/07/01 13:22

編集2019/07/01 13:54
gentaro

総合スコア8949

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

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

Kashi_wamochi

2019/07/01 13:38

返信ありがとうございます。恥ずかしながら、IDisposableについて全く無知でした...明日もう一度トライしてみます!
Zuishin

2019/07/01 13:50

StreamReader をクローズしたらファイルの方もクローズされるんじゃありませんでしたっけ? タイマーのコールバックが怪しそうです。
gentaro

2019/07/01 13:58

>Zuishinさん そう思うのですが、質問文に「OpenFileDialogを開き、選択ボタンを押した段階」とあるため、ちょっと不思議な感じはしてます。とりあえず両方直してみたらどうかな、と。
Zuishin

2019/07/01 14:02

どのみちそこは確かに直した方がいいですね。
Kashi_wamochi

2019/07/02 00:00

>Zuishinさん、Gentaroさん ご回答ありがとうございます。コードを指摘の通りusingステートメントを用いて書き換えましたが、同じタイミングで同じエラーメッセージが発生しました。 試しにメモ帳やNotepad++で開こうとしたところ、「別のプロセスを使用中です」とのエラーが出たため、ほかの方が仰られている通り、ログ作成の方のプログラムが怪しいと感じています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問