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

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

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

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

Visual Studio

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

Q&A

解決済

3回答

6031閲覧

C# ファイル読み込み時にNullReferenceExceptionが発生してしまう。

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

Visual Studio

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

0グッド

0クリップ

投稿2018/11/17 01:58

C#、visualstudioで開発しています。

下記のメソッドで指定したファイルを読み込み、配列を返すような処理をしています。

C#

1public string[] ReturnSetting(string path) { 2       //読み込むファイルパス 3 string filePath = ConfigurationManager.AppSettings["SensorPath"] + path; 4 //読み込み処理 5 using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 6 using (StreamReader sr = new StreamReader(fs)) { 7 //指定されたcsvファイルを配列に格納して返す 8 string[] cols = sr.ReadLine().Split(','); 9 return cols; 10 } 11 }

引数の"path"でcsvファイルを指定します。
csvファイルは19個あり"file_1.csv"のような具合で引数を渡しています。

あるイベントでこの処理を19回(引数1~19まで)行います。
ここで3回目くらいの時点で「NullReferenceException」が発生します。デバッグで1行ずつ実行すると

"string[] cols = sr.ReadLine().Split(',');"

ここの処理で例外が発生しているようです。
また、FileStream、StreamReaderともに値は入っていてました。

不思議なことに読み込むファイルをPC内ではなく、ファイルサーバー上に置いて実行するとエラーが発生しません。
ファイルパスの指定が間違っていると思い何回も確認しましたが、間違っている様子はありません。

なぜ1,2回目は成功するのでしょうか?また、なぜファイルサーバー上だと成功するのでしょうか?

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

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

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

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

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

papinianus

2018/11/17 02:09

前回の質問との違いは、ファイル置き場ですか?PCへの依存は関係なくなったのでしょうか?
退会済みユーザー

退会済みユーザー

2018/11/17 02:12

前回の質問まで閲覧いただき、ありがとうございます。前回質問時は、PCの依存関係だと思っていたのですが、どうやらファイルの置き場が問題のようなので新しく質問する形になりました。PCの依存関係はありませんでした。
Zuishin

2018/11/17 02:15

同じ質問なのでこの質問は削除依頼し、前の質問を編集して必要事項を追記してください。
mituha

2018/11/17 02:20

あ、前のがあったんですね。回答しちゃいました。
退会済みユーザー

退会済みユーザー

2018/11/17 02:22

すみませんでした。前回の質問を修正するべきでした。
guest

回答3

0

  • BA決定後の回答

(書き込みがあるっぽいのでファイルでやるのは微妙なのかもしれませんが)
そもそもそんなに小さいデータならFile.ReadAllText()とかFile.ReadAllLines()(ReadLinesですらなく)を使ったほうがいいのではないでしょうか?ストリームをもらう意図がわかりません。どんな機能も使いどころだと思います。

投稿2018/11/19 08:29

papinianus

総合スコア12705

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

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

退会済みユーザー

退会済みユーザー

2018/11/20 23:46

ご回答ありがとうございます。 確かにそちらを使ったほうが良さそうですね。勉強になりました。 今回の質問とは別のメソッドに書き込みの処理があるのですが、そちらはストリームで問題ないのでしょうか? また、同じファイルに対して読み書きしているので読込の部分だけFile.Readで問題ないのでしょうか?
papinianus

2018/11/21 00:02

排他処理は大丈夫なのですかね。 Fileのスタティックメソッドを使うかどうかは、サイズとかそれこそ排他とかで決まるので、streamにwriteするかFile.WriteAllTextにするかは処理次第だと思います。 ストリームをずっと保持してないなら、リードとライトで別の処理しても問題はないと思います
退会済みユーザー

退会済みユーザー

2018/11/21 00:56

元の質問とかけ離れてしまいすみません。。 排他処理はtry catchで例外が発生したら読込、書込のどちらかを実行中と判断し、メッセージを表示させています。 ファイル操作を行う処理は今回が初めてですので、streamかFileどちらを使うべきなのかがイマイチわからない状況です。 現状は読書どちらもstreamを使っていますがそのstreamは1つの処理(1行読込や1行書き込み、どんなに多くても19行20文字ずづ)をしたら閉じています。 このよう場合はFileクラスで十分こと足りているということなのでしょうか?
papinianus

2018/11/21 07:46 編集

その処理・データ量だとしたら、せっかくtry-catchを書いたのにcatchされることがないように思います(意図して同じタイミングで2PCで操作するみたいなことをしなければ)。 この処理・データ量だとしたら、エラーが発生しにくい分だけFileのスタティックメソッドが適しているように思います。 ただ、根本的な排他の問題を考えると、Aがリード、Bがリード、Bが書き込み、Aが書き込みといった順序でイベントが起こると、Bがやったことが(気づかれないまま)全くの無になる可能性があります(streamを使うか否かにかかわらずです)。本当にファイルでの処理が妥当なのでしょうか。
退会済みユーザー

退会済みユーザー

2018/11/21 08:07

詳しくご回答いただきありがとうございます。 確かに、書き込みの部分では意図的にやらない限りエラーは発生していないです。 書き込みの部分はFileを使おうと思います。ありがとうございます。 書き込みがされた時点で、必ずリードするようにするイベントがあるので誰かの書き込みが反映されない。 ということはないです。 しかし、そのイベントのせいで読込みが競合しエラーが発生してしまう現状です。。。
guest

0

おそらく3回目のファイル名のCSVファイルがカラなんじゃないでしょうか。
なので、Readlineはnullになると。

で、VisualStudioでワンステップづつ実行して、filePathの値がどうなってるのか見てみましょう。
# 特に3回目

そのパスが果たして正当なものであるのか、そのファイル名のファイルが存在するのか、そのファイルのナカミはどういうものであるかを調べましょうねっ

投稿2018/11/17 06:32

編集2018/11/17 06:35
y_waiwai

総合スコア87747

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

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

退会済みユーザー

退会済みユーザー

2018/11/19 06:13

ご回答ありがとうございます。 一行ずつ実行してみたところ、質問した部分とは別のメソッドで書き込みしようとしていたことが原因でした。 ありがとうございました。
guest

0

ベストアンサー

まず、状況の確認のために、ソースを変更してデバッグしやすいようにしてみてください。

string line = sr.ReadLine(); string[] cols = line.Split(',');

どちらの行でエラーが出ているかを確認し、
最初の行の場合、ドキュメントの StreamReader.ReadLine Method を確認してみてください。

投稿2018/11/17 02:16

mituha

総合スコア385

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

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

退会済みユーザー

退会済みユーザー

2018/11/17 02:33

ご回答ありがとうございます。 ソース変更後デバッグで確認したところ、"line"にnullが入ってしまっている状態でした。 ドキュメントのリンクありがとうございます。確認してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問