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

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

ただいまの
回答率

87.78%

ファイルの読みこみ、書き込み操作について

解決済

回答 5

投稿

  • 評価
  • クリップ 1
  • VIEW 3,348

score 15

質問内容
ファイルの読み込み書き込み操作をするときに、どんな処理が基本的に必要なのかを教えてください。

補足
今回ご教示していただきたい内容は、コードではなく処理の内容です。

取り扱うファイル
テキストファイルを扱います。
データ量としては10行くらいです。
記述された文字列を読み込んで画面に表示したり、変更した内容をファイルに書き込んだりします。
ただ自分の中ではテキストファイル以外(バイナリファイル等)であっても、基本的に求められる処理は同じなのかなと思っているので、テキストファイルを適正に操作する方法を学べば他のファイルも扱えるのかなと思っています。
勘違いしていたらすいません。

自分で思いつく処理内容
自分の中では以下のような操作で十分なのかなと思っていますが、ほかにも必要な処理があればご教示ください。
まだ扱ったことは無いのですがデッドロックや大容量のデータの扱いについては、今回は除外しています。

・ファイルを読み込む処理
1、読み込むファイルを指定する。
2、指定されたファイルが存在するかを確認する。
3、ファイルが存在しない場合は、仕様に応じてエラーメッセージを表示するか、プログラム側で新規に作成する。
4、読み込むファイルをロックする。
5、ファイルを読み込む。
6、読み込みが終了したらロックを外す。
7、読み込んだデータを画面に表示する処理をする。

・データをファイルに書き込む処理
1、書き込むファイルを指定する。
2、指定されたファイルが存在するかを確認する。
3、ファイルが存在しない場合は、仕様に応じてエラーメッセージを表示するか、プログラム側で新規に作成する。
4、書き込むファイルをロックする。
5、ファイルにデータを書き込む
6、書き込みが終了したらロックを外す。
7、終了

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

+4

自分の中では以下のような操作で十分なのかなと思っていますが、ほかにも必要な処理があればご教示ください。

扱うのはテキストファイルですよね?

であれば、質問者さんが列挙した以外のことで考えなければならないことに文字エンコーディングがあると思います。(個人的にはこれが一番重要なことではないかと思っています)

ファイルの中身は単純にバイト列ですが、プログラムから文字列をファイルに書き込むときにどの文字エンコーディングでバイト列に変換するか、ファイルからプログラムに文字列として読み込むときにファイルのバイト列がどの文字エンコーディングで書き込まれていたたかが分からないと何ともならないですよね。

一度、メモ帳で "あいうえお" などの文字をファイルに書き込んで、それをバイナリエディタで開いて見てください。メモ帳の「文字コード」オプションで ANSI, Unicode, Unicode big endian, UTF-8 が選択できますが、それぞれ結果は異なるはずです。

メモ帳で作ったテキストファイルなら、文字コードが Unicode, Unicode big endian, UTF-8 の場合は先頭に BOM が付くので、BOM がついていていれば BOM の指定どおり、付いてなければ Shift_JIS と判断できます。

StreamReader などを使ってもそのような実装ができます。

StreamReader コンストラクター (String, Encoding)
https://msdn.microsoft.com/ja-jp/library/x8xxf0x5(v=vs.100).aspx

"StreamReader  オブジェクトは、ストリームの最初の 3 バイトを参照して、エンコーディングの検出を試みます。 ファイルが該当するバイト順序マークで開始される場合は、UTF-8、リトル エンディアン Unicode、ビッグ エンディアン Unicode の各テキストが自動的に認識されます。 それ以外の場合は、ユーザー指定のエンコーディングが使用されます"

BOM がつかないテキストエディタで作ったテキストファイルですと、どの文字エンコーディングなのかを把握して、例えば上に紹介した StreamReader を使うならコンストラクターの第二引数 encoding に文字エンコーディングを指定しないと正しく解釈できず、結果文字化けするはずです。

注:kiichi54321 さんが紹介された File クラスを使う際も上に書いた文字エンコーディングへの配慮は必要です。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/10 22:04

    回答ありがとうございます。
    文字コードはあまり気にしたことが無かったのですが覚えておく必要がありますね。
    今まで自分の作ったアプリでかつ自分で作成したファイルしか扱ってなかったので、文字コードは自分指定なので問題はなかったのですが、もし他の人が作成したファイルを扱うようになったら文字化けで処理できなくなるのですね。
    覚えておくようにします。
    ありがとうございました。

    キャンセル

checkベストアンサー

+3

本来は、そういう面倒な処理やるのだけど、テキストファイルに関しては、大体は、
File.ReadLines
https://msdn.microsoft.com/ja-jp/library/dd383503(v=vs.110).aspx

File.WriteAllText
https://msdn.microsoft.com/ja-jp/library/ms143375(v=vs.110).aspx

を使えばよくて、せいぜい、
対象ファイルの存在確認、をして、
とりあえず、ファイル処理をしているところをTry Catchで囲んで例外処理をするくらいで十分です。

読み込むファイルをロックとかは、勝手にやってくれることなので、気にしなくていいです。
やっていることを、知っているのは重要ですけど。
(たまにはまるので、エクセルとかで)

また、Using文を使うことで、解放処理を勝手にやるので、Using文を使うところでちゃんと使いましょう。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/10 21:49

    回答ありがとうございます。
    ロックをする必要があると思い込んでいたのですが、そこはStreamReaderが行ってくれているのですね。
    ファイル読み込み中にsleep()をして、自分でテキストファイルを削除しようとしたのですが、できませんでした。
    テキストファイルの扱いが正しく分かりました。。
    テスト的に以下のようなコードでテキストを読み込んでみました。
    try catchとusingの合わせ技も適正に使えているか自信はありませんが以下のような形にしてみました。
    どうもありがとうございました。

    static void Main(string[] args)
    {
    // ファイルのパス
    string filePath = @"C:\Users\T534S\Desktop\test.txt";

    // ファイルの内容を格納する
    string contents = string.Empty;

    try
    {
    if (!File.Exists(filePath))
    {
    Console.WriteLine("ファイルを確認してください。");
    return;
    }

    using (var file = new StreamReader(filePath, System.Text.Encoding.GetEncoding("shift_jis")))
    {
    // ファイルを読み込む
    contents = file.ReadToEnd();

    // 10秒間停止
    System.Threading.Thread.Sleep(10000);
    }
    }
    catch (Exception ex)
    {
    // エラーメッセージを表示
    Console.WriteLine(ex.Message);
    }

    // ファイル内容を表示
    Console.WriteLine(contents);
    }

    キャンセル

+2

こんな感じでしょうか。

1.ファイルをオープンする
2.オープンがエラーなら、原因を見て適切な処理をする
3.ファイルから読む
4.読み込みでエラーが起これば、原因を見て適切な処理をする
5.EOFで無ければ読んだデータの処理をする
6.EOFで無い場合、繰り返しが必要なら3から繰り返す
7.EOFの場合、もしくは何らかの理由で途中で読むのをやめた場合は、ファイルをクローズする

これは、読み込んだ段階でEOFが分かる言語の場合です。
言語によっては、読む前にEOFであるかどうか判断する必要があります。
なお、EOFというのはEnd of File(これ以上読み込むデータがない状態)です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/10 21:53

    回答ありがとうございます。
    C#ではEOFを気にせずコードを組んでいますが、言語によってそういった処理があるのですね。
    これから先EOFを扱う処理があるかもしれないので覚えておくようにします。
    ありがとうございました。

    キャンセル

  • 2017/11/11 01:01

    すいません。質問文だけ見て、タグを見て無かったので、C#限定の質問だと気づきませんでした。
    > コードではなく処理の内容です。
    ということだったので、言語に依らない汎用的な話と思って回答しました。

    キャンセル

+2

テキストファイルを適正に操作する方法を学べば
他のファイルも扱えるのかなと思っています。

ご質問は汎用的な考えを求めていると思うので、
とくにエラー処理について解説したいと思います。
入門書などにあまり載ってない難しい部分だからです。


3、ファイルが存在しない場合は、
仕様に応じてエラーメッセージを表示するか、
プログラム側で新規に作成する。

ご質問で提示された手順でおおむね問題ないと思いますが、
今回はエラー処理がテーマなので、あえてくどく重箱の隅をつついてみましょう。

引用部でどういう問題が起こりうるか考えてみます。

ファイルがなく新規作成するとき、タイトルが未設定の場合、
「新規ファイル」といったデフォルトの名前で保存するでしょう。

しかしここで、2回目の場合に何が起こるでしょうか。
「新規ファイル」に上書きしてしまう挙動が起こりがちです。

多くの開発者の本音としては、「利用側が不注意だから悪いのだ」
と言いたくなるところです。しかし、注意が必要なのは使いにくいソフトです。

ここで、既存のテキストエディタなどだと、
「新規ファイル(2)」などと連番を振って、
勝手に上書きしない挙動をしますが、見たことがあるかと思います。
その方が使いやすいので、そういう処理を書いていきます。

そんなの分かる、と思うかもしれないので、
もう少し難しい処理としては、アンドゥ・リドゥの処理があります。
ファイルの保存もアンドゥできるという、
そういうテキストエディタがあるんです。

保存を巻き戻すときには、削除する処理が必要になります。
そうすると、テキスト編集中にフォルダの
ファイルをリネームすると消える可能性が出てきます。

だんだんエラー処理が難解になっていく様子がお分かりでしょうか。
こういう細かい面倒臭いケースが、それこそ100個とかあるわけです。

100個も網羅して説明できないので、どうやって想定すればいいかと言えば、
利用側の立場に回って考えることです。利用していた頃を思いだすとか、
既存のソフトの挙動やヘルプを見て、どうやって処理するのか研究するとか。

「秀丸」といった老舗のテキストエディタの
変更履歴などを見ると、その修正量に気が遠くなります。
20年直し続けてきた分量をイメージしてください。

まあ今は、便利なライブラリやフレームワークが
細かいところを代わりにやってくれたりしますが、
自分がライブラリやフレームワークの作成者に回る場合に、
こうした意図しないケースの対応が必要になってきます。

プログラミングは、動くだけなら意外と簡単で、
でも動いてからが本番で、使いやすくするのが難しいのです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/10 22:16

    回答ありがとうございます。
    全く考えたこともない内容でしたが凄く興味深かったです。
    エラー時は「ファイルが見つかりません」とだけメッセージを表示すればいいのかなと思っていましたが、いろんな処理の仕方があるのですね。
    しかもかなり複雑な内容の・・・。
    私も秀丸エディタを利用しているのですが、20年も更新されているなんて知りませんでした。
    「使いやすくていいエディタだな」と思っていただけでしたが、凄い技術の結晶だったのですね。
    プログラムは動かなきゃ意味がない、だけど動けばいいっていうところでしか考えていませんでしたが、動いてからが本番なんですね。
    勉強になりました。
    ありがとうございました。

    キャンセル

+1

  1. ファイルが開けなかった(ロックできなかった)
  2. 全データを読込、書込できなかった
  3. 読込データが正しくなかった(バリデーション)

も考慮しておいたほうがよいと思います。
また、これらの異常時、アプリケーションの状態(表示画面など)をどうするのか(クリアするかそのまま残しておくか)を決めておく必要があります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/10 21:57

    回答ありがとうございます。
    上記で挙げられている3つの内2番目と3番目については全く考えたことが無かったので、今後こういった点も視野に入れていきたいと思います。
    ありがとうございました。

    キャンセル

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

  • ただいまの回答率 87.78%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る