テキストファイルを扱う
.NET Frameworkを使ったテキストファイルの扱い方についてを説明していきます。
テキストファイルを読み込む
.NET Frameworkでファイルを扱うにはSystem.IOの中のクラスを使うのですが、BinaryReader、TextReader、StringReader、StreamReaderやFileなど同じようなことができそうなクラスがいっぱいあります。中には抽象基本クラスというものもあって、C++の知識がないとあれ?と思うものもあります。じゃあ全部覚える必要があるかというと、そんなことはありません。とりあえずいくつかの方法を試してみましょう。System.IO.File.ReadAllLinesを使う
簡単にスクリプトを組む人なら、まず次の使い方をお勧めします。from System.IO import File
filename = raw_input('ファイル名を入力してください:')
lines = File.ReadAllLines(filename) ←ここで読み込んでます。
print filename + 'の中身は次の以下の通りです。'
for line in lines:
print line
raw_input()
出力画面:
ファイル名を入力してください:tuple.py ←例えば"tuple.py"の場合
tuple.pyの中身は次の以下の通りです。
#coding: shift-jis
print tuple('ABCDE')
print tuple(['a','b','c'])
print tuple((1,2,3))
raw_input()
File.ReadAllLines()はテキスト ファイルを開き、ファイルのすべての行を文字列配列に読み取った後、ファイルを閉じます。 ファイルを開けたり、閉じたりを記述しなくていいんです。またファイル一気に読み、メモリに溜めますが大抵のテキストファイルの容量であれば、問題は起こしません(2ギガを超えると大変かな)。後はfor文を使って、各行について処理を行えば完了です。簡単ですね。でも次の場合もあります。
出力画面:
ファイル名を入力してください:hello.py ←例えば"hello.py"の場合
hello.pyの中身は次の以下の通りです。
# coding: shift-jis
print u"?????????O???????????????B"
name = raw_input()
print "Hello, "+ name + "!"
raw_input()
なんだ、この?????はと思いますよね。これは日本語コードの問題です。.NET Frameworkでは通常"UTF-8"を使いますが、今回のコードは"shift-jis"ですよね。この問題を解決するためにSystem.TextのEncodingクラスを使います。使い方は次の通りです。from System.IO import File
from System.Text import Encoding
filename = raw_input('ファイル名を入力してください:')
lines = File.ReadAllLines(filename, Encoding.GetEncoding("shift-jis"))
↑ここがポイント
print filename + 'の中身は次の以下の通りです。'
for line in lines:
print line
raw_input()
出力画面:
ファイル名を入力してください:hello.py ←例えば"hello.py"の場合
hello.pyの中身は次の以下の通りです。
# coding: shift-jis
print u"あなたの名前を教えてください。"
name = raw_input()
print "Hello, "+ name + "!"
raw_input()
System.IO.StreamReaderクラスを使う
Fileクラスでは1行で行ったことを数行に分けています。但しメモリの消費は少ないです。from System.IO import StreamReader
from System.Text import Encoding
filename = raw_input('ファイル名を入力してください:')
file = StreamReader(filename, Encoding.GetEncoding("shift-jis"))
print filename + 'の中身は次の以下の通りです。'
while not file.EndOfStream: ←fileが終わるまで繰り返します。
print file.ReadLine()
file.Close()
raw_input()
出力画面:
ファイル名を入力してください:hello.py ←例えば"hello.py"の場合
hello.pyの中身は次の以下の通りです。
# coding: shift-jis
print u"あなたの名前を教えてください。"
name = raw_input()
print "Hello, "+ name + "!"
raw_input()
テキストファイルを書き込む
System.IO.File.WriteAllLinesを使う
ReadAllLinesがファイルの内容を文字列配列にファイルの落としたように、今度は文字列配列をファイルに書き込む形を取ります。但しファイルが既存していた場合の細かな対応を指定できません。全て上書きされます。ファイルが既存していた場合の細かい指定は、後で説明するStreamWriterを使います。例を見てみましょう。
from System.IO import File
from System.Text import Encoding
filename = "test.txt"
lines = ["テストテスト","本日は晴天なり、本日は晴天なり"]
File.WriteAllLines(filename,lines, Encoding.GetEncoding("utf-8"))
↑今回のポイントの部分です。
lines2 = File.ReadAllLines(filename)
for line in lines2:
print line
raw_input()
出力画面:
テストテスト
本日は晴天なり、本日は晴天なり
File.WriteAllLines(filename,lines, Encoding.GetEncoding("utf-8"))上記のスクリプトではEncodingを指定しています。Defaultのままでもいいんですが、Encodingを指定してやるとファイルの一番最初に、"utf-8"のファイルである印を付けて保存されます。ソフトのよってはその印でファイルのEncodingをチェックしているものもあるので、行儀よい書き方としてEncodingを指定する書き方をお勧めします。
System.IO.StreamWriterクラスを使う
では今度はStreamWriterを使ってみましょう。from System.IO import *
from System.Text import Encoding
filename = "test.txt"
file = StreamWriter(filename, True, Encoding.GetEncoding("utf-8"))
↑今回のポイント
file.WriteLine("明日は雨天なり、明日は雨天なり")
file.Close()
lines2 = File.ReadAllLines(filename)
for line in lines2:
print line
raw_input()
出力画面:
テストテスト
本日は晴天なり、本日は晴天なり
明日は雨天なり、明日は雨天なり
上記の出力画面はFile.WriteAllLinesの例の続きで行ったので、"明日は雨天なり、本日は雨天なり"という文字列が追記されてた形になっています。StreamWriter(filename, True, Encoding.GetEncoding("utf-8"))
今回のポイントは上記スクリプトです。2番目の引数がTrueのbool値になっています。
データをファイルの末尾に追加するかどうかを判断します。ファイルが存在し、False の場合は、ファイルが上書きされます。ファイルが存在し、True の場合は、データがファイルの末尾に追加されます。それ以外の場合は、新しいファイルが作成されます。
もっと複雑な処理ができますが、取り合えずこれだけ触れていれば十分ではないでしょうか。