ファイルをbyte []に​​変換する信頼できる方法


84

私はウェブ上で次のコードを見つけました:

private byte [] StreamFile(string filename)
{
   FileStream fs = new FileStream(filename, FileMode.Open,FileAccess.Read);

   // Create a byte array of file stream length
   byte[] ImageData = new byte[fs.Length];

   //Read block of bytes from stream into the byte array
   fs.Read(ImageData,0,System.Convert.ToInt32(fs.Length));

   //Close the File Stream
   fs.Close();
   return ImageData; //return the byte data
}

ファイルをc#でbyte []に​​変換するために使用するのに十分な信頼性がありますか、それともこれを行うためのより良い方法がありますか?


3
が実際に呼び出されるfs.Close()ように、残りのコードを囲むtry-finallyステートメントのfinally-partを入力する必要がありますClose
Joren 2009

回答:


219
byte[] bytes = System.IO.File.ReadAllBytes(filename);

それでうまくいくはずです。ReadAllBytesはファイルを開き、その内容を新しいバイト配列に読み込んでから閉じます。これがそのメソッドのMSDNページです。


これによりファイルロックが発生しますか?
JL。

つまり、byte []が入力された後も、ファイルはロックされませんか?
JL。

3
いいえ、そうではありません。バイト配列が入力されるとすぐにファイルが閉じられます。
Erik Forbes

4
これに関する唯一の小さな問題は、大きなファイル(たとえば、500MBまたは1GBなど)がある場合、バイト配列にその量のメモリが割り当てられることです。そのため、.Read(..)をループして、ゆっくりと取り出すとよい場合があります。もちろん、それはすべてファイルサイズによって異なります。:)
Joshua

3
ファイルが別のプロセスによって開かれた場合、これは失敗します。OPメソッドは、FileShare.ReadWriteafterFile.Read
Motes

28
byte[] bytes = File.ReadAllBytes(filename) 

または..。

var bytes = File.ReadAllBytes(filename) 

13
真剣に?この場合、「var」は完全に受け入れられます。戻り値の型はメソッドの名前で明確に示されています...
Erik Forbes

4
元々使用していた場合は+1 var。可能な限り使用すべきであるというのが私の個人的な意見(そして他の多くの意見)です。:)この問題は、実際、以前にこのサイトで何度か議論されました。
ノルドール2009

8
また、varを使用するための+1 ... @silky、新しい言語機能が導入されたときに、誰もが新しい言語機能を使用するかどうかについて自由に意見を述べることができると思いますが、あなたの意見に従わないために答えを否定することはできませんこのフォーラムについて私が思ったのは。それは確かにJLの質問とはほとんど関係がありません。
チャールズブルターニュ2009

6
反対票を投じるときは、個人的な好み以上のものを考慮する必要があると思います。これは、の有無にかかわらず、完全に有効な答えですvar。型を手動で明示的に綴る必要のあるプログラマーは、抽象化のレベルが低すぎると思う傾向があります。変数の正確なタイプが何であるかは問題ではなく、変数が何のためのものであるかだけが重要です。ファイルのバイトを格納する場合は、それが重要です。リスト、配列、MyCustomContainerのいずれであるかではありません。
jalf 2009

8
もしがvar実際の答えにまったく関連していたら、それの使用について議論することは理にかなっているでしょう。しかし、ここでは、答えの重要な部分はただFile.ReadAllBytes(filename)です。結果が変数に格納される方法とかどうかは、変数の名前や=。の後のスペースとは無関係です。
jalf 2009

12

誰もがすでに言ったことを繰り返すのではなく、ファイル操作のために次のチートシートを手元に置いておきます。

  1. System.IO.File.ReadAllBytes(filename);
  2. File.Exists(filename)
  3. Path.Combine(folderName, resOfThePath);
  4. Path.GetFullPath(path); // converts a relative path to absolute one
  5. Path.GetExtension(path);

6

これらすべての答えは.ReadAllBytes()。別の同様の(コードをリファクタリングしようとしていたので、重複とは言いません)質問がSOでここで尋ねられました: C#で大きなファイルをバイト配列に読み込む最良の方法は?

以下に関する投稿の1つにコメントがありました.ReadAllBytes()

File.ReadAllBytes throws OutOfMemoryException with big files (tested with 630 MB file 
and it failed) – juanjo.arana Mar 13 '13 at 1:31

私にとってより良いアプローチは、次のようなものですBinaryReader

public static byte[] FileToByteArray(string fileName)
{
    byte[] fileData = null;

    using (FileStream fs = File.OpenRead(fileName)) 
    { 
        var binaryReader = new BinaryReader(fs); 
        fileData = binaryReader.ReadBytes((int)fs.Length); 
    }
    return fileData;
}

しかし、それは私だけです...

もちろん、これはすべて、byte[]一度読み込まれFile.Existsたファイルを処理するためのメモリがあることを前提としています。このコードを呼び出す前に行うように、先に進む前にファイルがそこにあることを確認するためのチェックを入れませんでした。


1
あなたのコードに誤りがあり、ご使用の文で新しいを必要としない、それは、(FileStreamをFS = File.OpenRead(ファイル名)を使用する必要があります
JoseR

エラーはそれほど多くありませんが(コードはまだコンパイルされると思います)、すべて同じように削除しました。良いキャッチ。
vapcguy 2018

3

ジェネリック版としては十分に良さそうです。十分に具体的であれば、ニーズに合わせて変更できます。

また、ファイルが存在しない、または読み取れないなどの例外やエラー状態をテストします。

スペースを節約するために、次のこともできます。

 byte[] bytes = System.IO.File.ReadAllBytes(filename);

2

他の人はあなたがビルトインを使うことができると述べましたFile.ReadAllBytes。組み込みの方法は問題ありませんが、上記のコードは2つの理由で壊れやすいことに注意してください。

  1. StreamですIDisposable-あなたは配置する必要がありFileStream fs = new FileStream(filename, FileMode.Open,FileAccess.Read)、ファイルが閉じていることを確認するために使用した句で初期化します。これを怠ると、障害が発生した場合にストリームが開いたままになる可能性があります。これは、ファイルがロックされたままになることを意味し、後で他の問題を引き起こす可能性があります。
  2. fs.Read要求よりも少ないバイトを読み取る可能性があります。一般に、インスタンスの.ReadメソッドはStream少なくとも1バイトを読み取りますが、必ずしもすべてのバイトを読み取る必要はありません。すべてのバイトが読み取られるまで読み取りを再試行するループを作成する必要があります。 このページでは、これについて詳しく説明しています。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.