100

I found the following code on the web:

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
}

Is it reliable enough to use to convert a file to byte[] in c#, or is there a better way to do this?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
JL.
  • 78,954
  • 126
  • 311
  • 459
  • 3
    You should put `fs.Close()` in the finally-part of a try-finally statement that encloses the rest of the code, to ensure `Close` is actually called. – Joren Sep 30 '09 at 14:06

7 Answers7

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

That should do the trick. ReadAllBytes opens the file, reads its contents into a new byte array, then closes it. Here's the MSDN page for that method.

Erik Forbes
  • 35,357
  • 27
  • 98
  • 122
  • Would this cause a file lock? – JL. Sep 30 '09 at 13:12
  • I mean - once the byte[] is populated, won't the file still be locked? – JL. Sep 30 '09 at 13:14
  • 3
    No, it wouldn't - the file is closed as soon as the byte array is populated. – Erik Forbes Sep 30 '09 at 13:15
  • 5
    Only *minor* issue with this is, if you have a large file (say 500MB or 1GB, etc.) it'll allocate that much memory for your byte array. So sometimes it pays to loop around a .Read(..) and take it out slowly. Of course, that all depends on your file size. :) – Joshua Sep 30 '09 at 14:47
  • And it depends on what you want to do with the file - if you can process it in chunks, then it would definitely pay to read it incrementally as you suggest. Good call. – Erik Forbes Sep 30 '09 at 15:17
  • 3
    This will fail if the file is opened by another process, the OP method will work with the addition of `FileShare.ReadWrite` after `File.Read` – Motomotes Jan 01 '16 at 03:01
33
byte[] bytes = File.ReadAllBytes(filename) 

or ...

var bytes = File.ReadAllBytes(filename) 
Brian Rasmussen
  • 114,645
  • 34
  • 221
  • 317
  • Come on. Anyway, I'll change it if it makes you feel any better. – Brian Rasmussen Sep 30 '09 at 13:15
  • 14
    Seriously? 'var' is perfectly acceptable in this case - the return type is clearly stated in the name of the method... – Erik Forbes Sep 30 '09 at 13:16
  • 1
    *sigh*, you changed it too fast, I can't remove the vote yet (I'll need to edit it). It is my personal opinion that `var` should only be used where absolutely necessary, and I expressed it via voting, that is all :) – Noon Silk Sep 30 '09 at 13:17
  • Erik: I glaze over method names, I only look at types. Obviously it can be inferred pretty easily from the variable name, and the IDE itself, and so many other things; I am merely expressing personal preference. – Noon Silk Sep 30 '09 at 13:18
  • So, you only use 'var' when using anonymous types? – Erik Forbes Sep 30 '09 at 13:18
  • 2
    Thanks Erik - I like use of "var" and in this case it was a few strokes shorter. I take it that the OP would get the gist anyway. – Brian Rasmussen Sep 30 '09 at 13:18
  • 4
    +1 for originally using `var`. It is my personal opinion (and that of many others), that it should be used as much as possible. :) The matter has been discussed several times on this site before, in fact. – Noldorin Sep 30 '09 at 13:19
  • Sorry if I came across as arguing - I've just never met anyone with that particular preference before. It's a little baffling to be honest. I don't use it *everywhere* I can (sorry Noldorin) but I do try to use it anywhere that the type can be inferred from its initialization. – Erik Forbes Sep 30 '09 at 13:21
  • 9
    Also +1 for using var... @silky, I guess everyone is free to have an opinion about whether or not to use new language features when they are introduced, but downvoting an answer because it doesn't conform to your opinion is not what I thought this forum was about. it certainly has little to do with JLs question. – Charles Bretana Sep 30 '09 at 13:25
  • 6
    I think you should consider more than personal preference when downvoting. This is a perfectly valid answer, with or without `var`. I tend to think that any programmer who needs to manually and explicitly spell out types is working at a too low level of abstraction. It shouldn't *matter* what the precise type of the variable is, only what the variable *is for*. If it stores the bytes from the file, then that should be what matters. Not whether it is a List or an Array or MyCustomContainer. – jalf Sep 30 '09 at 13:30
  • Charles: Well, you're wrong on your second statement. But I refuse to waste more time discussing it; I would think that a reasonable man can determine my reason for downvoting (even though I also stated it). – Noon Silk Sep 30 '09 at 13:30
  • 2
    Final statement as it seems that what I would consider obvious is not: I downvoted because *I* consider that it makes code confusing with no benefit. Furthermore, the voting system allows me (and all of us) to place posts in an order that they think is most relevant for the OP, and the readers of the website *at large*. In my opinion, using var for no reason is not good; hence the downvoted, and my upvote on the accepted answer. Let us further note that my vote is also retracted from this specific post, regardless. No more needs to be said. – Noon Silk Sep 30 '09 at 13:33
  • @silky: I realize this dialogue has gotten a little off-track, but here is a sincere question. What do you mean by "only be used when absolutely necessary"? Is var ever absolutely necessary? You can always make anonymous types explicit (as much a pain as it would be) and so even in that case is not "absolutely necessary." And given your preferences, your downvote is understandable. – jason Sep 30 '09 at 13:35
  • Jason: I'll be honest; I don't use 3.5 that much, and even when I do, I don't find myself using `var`. I don't use a lot of LINQ or anonymous classes, so I can't speak directly as to when it would be *specifically* necessary, but those are the cases I'm thinking of (LINQ and anonymous classes). – Noon Silk Sep 30 '09 at 13:35
  • 8
    If the `var` had been at all relevant to the actual answer, arguing over the use of it would have made sense. But here, the important part of the answer is just `File.ReadAllBytes(filename)`. How and if the result is stored in a variable is as irrelevant as the naming of the variable, or the space after the `=`. – jalf Sep 30 '09 at 13:36
  • 2
    @jalf: This voter (silky) has a preference that var not be used unless absolutely necessary. That is, given two otherwise identical posts but where one uses `byte[] bytes = File.ReadAllBytes(filename)` and the other uses `var bytes = File.ReadAllBytes(filename)`, he would prefer the former over the latter. That is, he would prefer that the former be ranked higher than the latter. Therefore, to express his preference, he should downvote the one using `var`. You might not use the voting system that way, but it is a perfectly reasonable use of the voting system to express his preference. – jason Sep 30 '09 at 13:40
  • 2
    I personally like to avoid using `var` just so the type is readily apparent, if known. So I avoid it like the plague for that reason - I don't like guessing about the return type of an object, or how to cast it, and tracing back over someone's code to find out. That said, I would never, EVER downvote a person's post on here for using it, since sometimes it's just to save some keystrokes when the OP will obviously know what type was intended. – vapcguy Oct 12 '16 at 00:23
  • I guess I was under the impression that downvoting an answer meant that it didn't answer the original question. In this case, var is a correct answer, as well as byte[], therefore both are correct answers. Seems crazy to me to DOWNVOTE an answer that is correct. – ganders Apr 30 '18 at 17:29
12

Not to repeat what everyone already have said but keep the following cheat sheet handly for File manipulations:

  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);
Vivek
  • 16,360
  • 5
  • 30
  • 37
7

All these answers with .ReadAllBytes(). Another, similar (I won't say duplicate, since they were trying to refactor their code) question was asked on SO here: Best way to read a large file into a byte array in C#?

A comment was made on one of the posts regarding .ReadAllBytes():

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

A better approach, to me, would be something like this, with 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;
}

But that's just me...

Of course, this all assumes you have the memory to handle the byte[] once it is read in, and I didn't put in the File.Exists check to ensure the file is there before proceeding, as you'd do that before calling this code.

vapcguy
  • 7,097
  • 1
  • 56
  • 52
  • 1
    There is an error in your code, you don't need the new in the using statement it must be using (FileStream fs = File.OpenRead(fileName) – JoseR Mar 31 '18 at 13:47
  • Not so much an error (I believe the code would still compile) but I removed it all the same. Good catch. – vapcguy Apr 02 '18 at 16:30
3

looks good enough as a generic version. You can modify it to meet your needs, if they're specific enough.

also test for exceptions and error conditions, such as file doesn't exist or can't be read, etc.

you can also do the following to save some space:

 byte[] bytes = System.IO.File.ReadAllBytes(filename);
vehomzzz
  • 42,832
  • 72
  • 186
  • 216
2

Others have noted that you can use the built-in File.ReadAllBytes. The built-in method is fine, but it's worth noting that the code you post above is fragile for two reasons:

  1. Stream is IDisposable - you should place the FileStream fs = new FileStream(filename, FileMode.Open,FileAccess.Read) initialization in a using clause to ensure the file is closed. Failure to do this may mean that the stream remains open if a failure occurs, which will mean the file remains locked - and that can cause other problems later on.
  2. fs.Read may read fewer bytes than you request. In general, the .Read method of a Stream instance will read at least one byte, but not necessarily all bytes you ask for. You'll need to write a loop that retries reading until all bytes are read. This page explains this in more detail.
Eamon Nerbonne
  • 47,023
  • 20
  • 101
  • 166
0
string filePath= @"D:\MiUnidad\testFile.pdf";
byte[] bytes = await System.IO.File.ReadAllBytesAsync(filePath);
Yudner
  • 533
  • 4
  • 9