2009-09-30 12 views
63

Znalazłem następujący kod na stronie:niezawodny sposób przekonwertować plik do byte []

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 
} 

Jest on na tyle wiarygodne, aby użyć do konwersji pliku do byte [] w C#, czy istnieje lepszy sposób na zrobienie tego?

+3

Powinieneś umieścić 'fs.Close()' w końcowej części instrukcji try-finally, która zamyka resztę kodu, aby upewnić się, że 'Close' jest rzeczywiście wywoływany. – Joren

Odpowiedz

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

To powinno załatwić sprawę. ReadAllBytes otwiera plik, odczytuje jego zawartość do nowej tablicy bajtów, a następnie zamyka ją. Oto MSDN page dla tej metody.

+0

Czy spowodowałoby to blokadę pliku? –

+0

Mam na myśli - po zapełnieniu bajta [], czy plik nie zostanie zablokowany? –

+2

Nie, nie będzie - plik zostanie zamknięty, gdy tylko zostanie wypełniona tablica bajtów. –

3

wygląda wystarczająco dobrze jako wersja generyczna. Możesz go zmodyfikować zgodnie z własnymi potrzebami, jeśli są wystarczająco szczegółowe.

również przetestować wyjątków i warunków błędach, takich jak plik nie istnieje lub nie można go odczytać, itp

można także wykonać następujące czynności, aby zaoszczędzić trochę miejsca:

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

lub ...

+0

Rewizja za niedorzeczne użycie 'var' (tylko wyjaśnienie mojego powodu). –

+0

Chodź. W każdym razie zmienię to, jeśli sprawi, że poczujesz się lepiej. –

+9

Poważnie? "var" jest całkowicie do przyjęcia w tym przypadku - typ zwrotu jest wyraźnie określony w nazwie metody ... –

2

Inni zauważyli, że można użyć wbudowanej File.ReadAllBytes. Wbudowana metoda jest w porządku, ale warto zauważyć, że kod piszesz powyżej jest kruche z dwóch powodów:

  1. Stream jest IDisposable - należy umieścić inicjalizacji FileStream fs = new FileStream(filename, FileMode.Open,FileAccess.Read) w wykorzystaniem klauzuli, aby zapewnić, że plik jest zamknięty . Niewykonanie tej czynności może oznaczać, że strumień pozostanie otwarty, jeśli wystąpi awaria, co będzie oznaczać, że plik pozostanie zablokowany - i że może to spowodować później inne problemy.
  2. fs.Read może odczytywać mniej bajtów niż żądasz. Ogólnie rzecz biorąc, metoda .Read instancji odczyta co najmniej jeden bajt, ale niekoniecznie wszystkie bajty, o które pytasz. Będziesz musiał napisać pętlę, która będzie ponawiać czytanie do momentu odczytania wszystkich bajtów. This page wyjaśnia to bardziej szczegółowo.
9

nie powtarzać tego, co wszyscy już powiedzieli, ale zachować następujące cheaty Handly arkuszy do manipulacji Plik:

  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);
1

Wszystkie te odpowiedzi z .ReadAllBytes().Inna, podobna (nie powiem duplikat, ponieważ zostały one próbuje byłaby ich kodu) padło pytanie na SO tutaj: Best way to read a large file into a byte array in C#?

Komentarz został wykonany na jednym ze stanowisk dotyczących .ReadAllBytes():

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

lepszym rozwiązaniem dla mnie byłoby coś takiego, z BinaryReader:

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

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

Ale to tylko ja ...

Oczywiście zakłada to, że masz pamięć do obsługi byte[] po jej wczytaniu, a ja nie wstawiłem do sprawdzenia, czy plik jest tam przed kontynuowaniem.

Powiązane problemy