「C Sharpの基礎 - ファイル」の版間の差分
細 Wiki がページ「バイナリファイルを読み書きする(C Sharp)」を「C Sharpの基礎 - バイナリファイルの読み書き」に、リダイレクトを残さずに移動しました |
編集の要約なし |
||
| 1行目: | 1行目: | ||
== | == バイナリファイル == | ||
==== バイナリファイルの読み込みと書き込み ==== | |||
ファイルの内容をすべてbyte配列に読み込む、または、byte配列全体をファイルに書き込む場合、<br> | ファイルの内容をすべてbyte配列に読み込む、または、byte配列全体をファイルに書き込む場合、<br> | ||
Fileクラス(System.IO名前空間)のReadAllBytesメソッドおよびWriteAllBytesメソッドを使用する。<br> | Fileクラス(System.IO名前空間)のReadAllBytesメソッドおよびWriteAllBytesメソッドを使用する。<br> | ||
| 12行目: | 13行目: | ||
</source> | </source> | ||
<br> | <br> | ||
==== サンプルコード(バイナリファイルを固定サイズで分割する) ==== | |||
== サンプルコード(バイナリファイルを固定サイズで分割する) == | |||
次のサンプルコードは、ReadAllBytesメソッドとWriteAllBytesメソッドを使用したサンプルコードである。<br> | 次のサンプルコードは、ReadAllBytesメソッドとWriteAllBytesメソッドを使用したサンプルコードである。<br> | ||
このプログラムでは、バイナリファイルを読み込み、それを固定サイズ(サイズ : 1[MB])の複数ファイルに分割して出力する。<br> | このプログラムでは、バイナリファイルを読み込み、それを固定サイズ(サイズ : 1[MB])の複数ファイルに分割して出力する。<br> | ||
尚、出力する最後のファイルは固定サイズに満たない場合がある。<br> | 尚、出力する最後のファイルは固定サイズに満たない場合がある。<br> | ||
<syntaxhighlight lang="C#"> | |||
< | |||
using System; | using System; | ||
using System.IO; | using System.IO; | ||
| 50行目: | 49行目: | ||
} | } | ||
} | } | ||
</ | </syntaxhighlight> | ||
<br> | <br> | ||
ReadAllBytesメソッドは、ファイル全体を一度に読み込むため、巨大なファイルを扱う場合には、<br> | ReadAllBytesメソッドは、ファイル全体を一度に読み込むため、巨大なファイルを扱う場合には、<br> | ||
読み込みに掛かる時間や使用するメモリ量について注意が必要である。<br><br> | 読み込みに掛かる時間や使用するメモリ量について注意が必要である。<br> | ||
<br> | |||
== サンプルコード(非同期でバイナリファイルを読み書きする) == | ==== サンプルコード(非同期でバイナリファイルを読み書きする) ==== | ||
バイナリファイルへ書き込んだ後、それを読み込むサンプルコードに示す。<br> | バイナリファイルへ書き込んだ後、それを読み込むサンプルコードに示す。<br> | ||
この例では、書き込み用に開くときにFileMode.Createを指定しているので上書きになる。(追記する場合 : FileMode.Append)<br> | この例では、書き込み用に開くときにFileMode.Createを指定しているので上書きになる。(追記する場合 : FileMode.Append)<br> | ||
< | <syntaxhighlight lang="c#"> | ||
async Task BinaryReadWriteAsync(byte[] data) | async Task BinaryReadWriteAsync(byte[] data) | ||
{ | { | ||
| 98行目: | 97行目: | ||
WriteLine(); | WriteLine(); | ||
} | } | ||
</syntaxhighlight> | |||
<br><br> | |||
== テキストファイル == | |||
==== テキストファイルの読み込みと書き込み ==== | |||
StreamReaderクラスを使用したテキストファイルの読み込み、using構文によるファイルのクローズ、例外処理など、<br> | |||
.NET Frameworkにおけるテキストファイルの読み込みの基本を解説する。<br> | |||
<br> | |||
テキストファイルの内容を読み込むには、以下の3つの処理からなる。<br> | |||
# '''ファイルを開く''' | |||
# '''ファイルの内容を読み込む''' | |||
# '''ファイルを閉じる''' | |||
<br> | |||
==== テキストファイルを開く ==== | |||
ファイルを開くには幾つかの記述方法があるが、UTF-8のファイルをファイル名を指定して開くには、<br> | |||
StreamReaderクラス(System.IO名前空間)を次のようにして使用するのが最も簡便である。<br> | |||
<syntaxhighlight lang="c#"> | |||
StreamReader sr = new StreamReader(@"readme.txt", Encoding.UTF8); | |||
</source> | </source> | ||
<br> | <br> | ||
また、Windowsで最も一般的に使用されているShift-JISのファイルを開くには次のようにする。<br> | |||
<source lang="c#"> | |||
StreamReader sr = new StreamReader(@"readme.txt", Encoding.GetEncoding("Shift_JIS")); | |||
</syntaxhighlight> | |||
<br> | |||
==== テキストファイルを読み込む ==== | |||
StreamReaderクラスのReadToEndメソッドを使用することで、ファイルの内容を全て1つの文字列に読み込むことができる。<br> | |||
ReadToEndメソッドでは、改行文字等も含めて全ての1つの文字列として読み込まれる。<br> | |||
<br> | |||
==== usingステートメントを使用してファイルを閉じる ==== | |||
StreamReaderクラスはIDisposableインタフェースを実装しているため(スーパークラスのTextReaderクラスが実装している)、<br> | |||
Closeメソッドの代わりにusingステートメントを利用することも出来る。<br> | |||
usingステートメントの実行を終えた時、自動的にStreamReaderクラスのDisposeメソッドを呼び出して、<br> | |||
その中でCloseメソッドが呼び出される。<br> | |||
<br> | |||
==== ファイルが読み込めない時のエラー処理 ==== | |||
開こうとするファイルが存在しない場合やファイルの読み込み中にディスク等に何らかの障害が発生した場合、<br> | |||
例外が発生してプログラムの実行が中断されるので、例外処理を記述する必要がある。<br> | |||
<br> | |||
==== サンプルコード(ファイルの内容を全て1つの文字列に読み込む) ==== | |||
<syntaxhighlight lang="c#"> | |||
using System; | |||
using System.IO; | |||
using System.Text; | |||
string text = string.Empty; | |||
try | |||
{ | |||
using (StreamReader sr = new StreamReader(@"hoge.txt", Encoding.UTF8)) | |||
{ | |||
text = await sr.ReadToEndAsync(); | |||
} | |||
Console.Write(text); | |||
} | |||
catch (Exception ex) | |||
{ | |||
Console.WriteLine(ex.Message); | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
==== サンプルコード(ファイルの内容を1行ずつ読み込む) ==== | |||
処理によっては、ファイル全体を1つの文字列として読み込むよりも、1行ずつ読み込んで文字列の配列にした方が扱いやすい場合がある。<br> | |||
ファイルから1行読み込むには、ReadLineメソッドを使用する。<br> | |||
ReadLineメソッドは、StreamReaderクラスにより開いたファイルから1行だけ読み取り、内部の読み取り位置を1行分進める。<br> | |||
読み取り位置がファイルの最後に達した場合はnullを返す。<br> | |||
<syntaxhighlight lang="c#"> | |||
using System; | |||
using System.IO; | |||
using System.Text; | |||
using System.Collections; | |||
string line = string.Empty; | |||
List<string> list = new List<string>(); | |||
try | |||
{ | |||
using (StreamReader sr = new StreamReader(@"hoge.txt", Encoding.UTF8)) | |||
{ | |||
while ((line = await sr.ReadLineAsync()) != null) | |||
{ | |||
list.Add(line); | |||
} | |||
} | |||
} | |||
catch (Exception ex) | |||
{ | |||
Console.WriteLine(ex.Message); | |||
} | |||
foreach (string strLine in list) | |||
{ | |||
Console.WriteLine(strLine); | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
尚、.NET Framework 2.0以降ではファイルを開き、内容を読み込み、閉じるという一連の処理を1つのメソッドで出来るReadAllTextメソッドと<br> | |||
ReadAllLinesメソッドがFileクラス(System.IO名前空間)に追加されている。<br> | |||
<br> | |||
==== サンプルコード(File.ReadAllTextメソッドによる文字列への読み込み) ==== | |||
テキストファイル全体を1つの文字列に読み込む場合は、FileクラスのReadAllTextメソッドが利用できる。<br> | |||
ReadAllTextメソッドで使用するデフォルトの文字コードは、UTF-8である。<br> | |||
以下にこれを使ったサンプルコードを示す。<br> | |||
<syntaxhighlight lang="c#"> | |||
using System.Text; | |||
using System.IO; | |||
try | |||
{ // ファイルの読み込み | |||
string text1 = File.ReadAllText(@"hoge.txt", Encoding.UTF8); | |||
} | |||
catch (Exception ex) | |||
{ | |||
Console.WriteLine(ex.Message); | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
==== サンプルコード(File.ReadAllLinesメソッドによる文字列配列への読み込み) ==== | |||
読み込んだテキストを1行ずつ処理する場合は、各行を要素とする文字列配列を使用する方が便利である。<br> | |||
これを行うのがFileクラスのReadAllLinesメソッドである。ReadAllLinesメソッドで使用するデフォルトの文字コードは、UTF-8である。<br> | |||
以下に、ReadAllLinesメソッドを使ったサンプルコードを示す。<br> | |||
<syntaxhighlight lang="c#"> | |||
using System.Text; | |||
using System.IO; | |||
try | |||
{ // ファイルの読み込み | |||
string[] lines1 = File.ReadAllLines(@"hoge.txt", Encoding.UTF8); | |||
} | |||
catch (Exception ex) | |||
{ | |||
Console.WriteLine(ex.Message); | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
尚、ReadAllLinesメソッドはファイル末尾の改行文字を無視する。<br> | |||
ファイル末尾に改行文字がある場合、ReadAllLinesメソッドで得られる行数は1行少なくなる。<br> | |||
<br><br> | |||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:C_Sharp]] | [[カテゴリ:C_Sharp]] | ||
2021年3月5日 (金) 12:28時点における版
バイナリファイル
バイナリファイルの読み込みと書き込み
ファイルの内容をすべてbyte配列に読み込む、または、byte配列全体をファイルに書き込む場合、
Fileクラス(System.IO名前空間)のReadAllBytesメソッドおよびWriteAllBytesメソッドを使用する。
これらのメソッド(静的)では、ファイルを開く、byte配列への読み込みまたはbyte配列の書き込み、ファイルを閉じるという3つの処理を
ReadAllBytesメソッドで実行可能である。
ReadAllBytesメソッドは、読み込むファイルのパス名をパラメータに指定して呼ぶと、戻り値としてファイルの内容を読み込んだbyte配列を返す。
また、WriteAllBytesメソッドでは、書き込むファイルのパス名(ファイルが存在する場合は上書き)と書き込むbyte配列をパラメータで指定する。
尚、WriteAllBytesメソッドの戻り値はない。
byte[] data = File.ReadAllBytes(@"hoge.bin"); // 読み込み
File.WriteAllBytes(@"newhoge.bin", data); // 書き込み
サンプルコード(バイナリファイルを固定サイズで分割する)
次のサンプルコードは、ReadAllBytesメソッドとWriteAllBytesメソッドを使用したサンプルコードである。
このプログラムでは、バイナリファイルを読み込み、それを固定サイズ(サイズ : 1[MB])の複数ファイルに分割して出力する。
尚、出力する最後のファイルは固定サイズに満たない場合がある。
using System;
using System.IO;
class BinarySplit
{
static void Main()
{
// バイナリファイルの読み込み
byte[] src = File.ReadAllBytes(@"hoge.bin");
int FILESIZE = 1024 * 1024; // 分割サイズ
int num = 0;
for (int remain = src.Length; remain > 0; remain -= FILESIZE)
{
int length = Math.Min(FILESIZE, remain); // 作成する分割ファイルの実際のサイズ
byte[] dest = new byte[length]; // 分割ファイルへ書き出すbyte配列の作成
Array.Copy(src, num * FILESIZE, dest, 0, length);
// 出力ファイル名(out0001.bin、out0002.bin、……)
string name = String.Format("out{0:D4}.bin", num + 1);
// byte配列のファイルへの書き込み
File.WriteAllBytes(name, dest);
num++;
}
}
}
ReadAllBytesメソッドは、ファイル全体を一度に読み込むため、巨大なファイルを扱う場合には、
読み込みに掛かる時間や使用するメモリ量について注意が必要である。
サンプルコード(非同期でバイナリファイルを読み書きする)
バイナリファイルへ書き込んだ後、それを読み込むサンプルコードに示す。
この例では、書き込み用に開くときにFileMode.Createを指定しているので上書きになる。(追記する場合 : FileMode.Append)
async Task BinaryReadWriteAsync(byte[] data)
{
const string FilePath = @".\sample.dat"; // 読み書きするファイル
// バイナリファイルへ書き込み
// ファイルを上書きモードで開く(ファイルが存在しない場合は作成)
// 追加モードにするにはFileModeをAppendに変える
using (var fs = new FileStream(FilePath, FileMode.Create, FileAccess.Write))
{
await fs.WriteAsync(data, 0, data.Length); // バイナリデータを非同期で書き込む
}
// バイナリファイル読み込み
byte[] result; // データを格納する配列
// ファイルを読み取りモードで開く
using (var fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read))
{
result = new byte[fs.Length]; // データ格納用の配列を確保する
// バイナリデータを非同期で読み込む
await fs.ReadAsync(result, 0, (int)fs.Length);
}
// 読み込んだ内容をコンソールへ出力する
for (int i=0; i < result.Length; i++)
{
Write($"{result[i]:X2} ");
if (i % 16 == 7)
{
Write(" ");
}
else if (i % 16 == 15)
{
WriteLine();
}
}
WriteLine();
}
テキストファイル
テキストファイルの読み込みと書き込み
StreamReaderクラスを使用したテキストファイルの読み込み、using構文によるファイルのクローズ、例外処理など、
.NET Frameworkにおけるテキストファイルの読み込みの基本を解説する。
テキストファイルの内容を読み込むには、以下の3つの処理からなる。
- ファイルを開く
- ファイルの内容を読み込む
- ファイルを閉じる
テキストファイルを開く
ファイルを開くには幾つかの記述方法があるが、UTF-8のファイルをファイル名を指定して開くには、
StreamReaderクラス(System.IO名前空間)を次のようにして使用するのが最も簡便である。
StreamReader sr = new StreamReader(@"readme.txt", Encoding.UTF8);
</source>
<br>
また、Windowsで最も一般的に使用されているShift-JISのファイルを開くには次のようにする。<br>
<source lang="c#">
StreamReader sr = new StreamReader(@"readme.txt", Encoding.GetEncoding("Shift_JIS"));
テキストファイルを読み込む
StreamReaderクラスのReadToEndメソッドを使用することで、ファイルの内容を全て1つの文字列に読み込むことができる。
ReadToEndメソッドでは、改行文字等も含めて全ての1つの文字列として読み込まれる。
usingステートメントを使用してファイルを閉じる
StreamReaderクラスはIDisposableインタフェースを実装しているため(スーパークラスのTextReaderクラスが実装している)、
Closeメソッドの代わりにusingステートメントを利用することも出来る。
usingステートメントの実行を終えた時、自動的にStreamReaderクラスのDisposeメソッドを呼び出して、
その中でCloseメソッドが呼び出される。
ファイルが読み込めない時のエラー処理
開こうとするファイルが存在しない場合やファイルの読み込み中にディスク等に何らかの障害が発生した場合、
例外が発生してプログラムの実行が中断されるので、例外処理を記述する必要がある。
サンプルコード(ファイルの内容を全て1つの文字列に読み込む)
using System;
using System.IO;
using System.Text;
string text = string.Empty;
try
{
using (StreamReader sr = new StreamReader(@"hoge.txt", Encoding.UTF8))
{
text = await sr.ReadToEndAsync();
}
Console.Write(text);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
サンプルコード(ファイルの内容を1行ずつ読み込む)
処理によっては、ファイル全体を1つの文字列として読み込むよりも、1行ずつ読み込んで文字列の配列にした方が扱いやすい場合がある。
ファイルから1行読み込むには、ReadLineメソッドを使用する。
ReadLineメソッドは、StreamReaderクラスにより開いたファイルから1行だけ読み取り、内部の読み取り位置を1行分進める。
読み取り位置がファイルの最後に達した場合はnullを返す。
using System;
using System.IO;
using System.Text;
using System.Collections;
string line = string.Empty;
List<string> list = new List<string>();
try
{
using (StreamReader sr = new StreamReader(@"hoge.txt", Encoding.UTF8))
{
while ((line = await sr.ReadLineAsync()) != null)
{
list.Add(line);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
foreach (string strLine in list)
{
Console.WriteLine(strLine);
}
尚、.NET Framework 2.0以降ではファイルを開き、内容を読み込み、閉じるという一連の処理を1つのメソッドで出来るReadAllTextメソッドと
ReadAllLinesメソッドがFileクラス(System.IO名前空間)に追加されている。
サンプルコード(File.ReadAllTextメソッドによる文字列への読み込み)
テキストファイル全体を1つの文字列に読み込む場合は、FileクラスのReadAllTextメソッドが利用できる。
ReadAllTextメソッドで使用するデフォルトの文字コードは、UTF-8である。
以下にこれを使ったサンプルコードを示す。
using System.Text;
using System.IO;
try
{ // ファイルの読み込み
string text1 = File.ReadAllText(@"hoge.txt", Encoding.UTF8);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
サンプルコード(File.ReadAllLinesメソッドによる文字列配列への読み込み)
読み込んだテキストを1行ずつ処理する場合は、各行を要素とする文字列配列を使用する方が便利である。
これを行うのがFileクラスのReadAllLinesメソッドである。ReadAllLinesメソッドで使用するデフォルトの文字コードは、UTF-8である。
以下に、ReadAllLinesメソッドを使ったサンプルコードを示す。
using System.Text;
using System.IO;
try
{ // ファイルの読み込み
string[] lines1 = File.ReadAllLines(@"hoge.txt", Encoding.UTF8);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
尚、ReadAllLinesメソッドはファイル末尾の改行文字を無視する。
ファイル末尾に改行文字がある場合、ReadAllLinesメソッドで得られる行数は1行少なくなる。