2011-12-30 15 views
27

Czy istnieje sposób na odczytanie określonych bajtów z pliku?C# - Czytanie określonych bajtów pliku

Na przykład, mam następujący kod do odczytu wszystkie bajty pliku

byte[] test = File.ReadAllBytes(file); 

Chcę przeczytać bajtów z przesunięciem 50 do offsetu 60 i umieścić je w tablicy.

Odpowiedz

12

LINQ Wersja:

byte[] test = File.ReadAllBytes(file).Skip(50).Take(10).ToArray(); 
+39

Tutaj cała zawartość pliku zostanie odczytana, a następnie zostanie użyte tylko 10 bajtów. Niezbyt optymalne podejście :) –

+1

@the_joric Jednak helper, który podał nazwę pliku, zwrócił leniwy 'IEnumerable ' w miejsce 'File.ReadAllBytes' byłby skutecznym podejściem, szczególnie jeśli odczytywanie dowolnego przebiegu bajtów z pliku było wspólna potrzeba. – Richard

+7

nie powinno to być zaakceptowaną odpowiedzią – neo112

26

to powinien to zrobić

var data = new byte[10]; 
int actualRead; 

using (FileStream fs = new FileStream("c:\\MyFile.bin", FileMode.Open)) { 
    fs.Position = 50; 
    actualRead = 0; 
    do { 
     actualRead += fs.Read(data, actualRead, 10-actualRead); 
    } while (actualRead != 10 && fs.Position < fs.Length); 
} 

Po zakończeniu data będzie zawierać 10 bajtów między plik offset 50 i 60 i actualRead będzie zawierać liczbę od 0 do 10, co wskazuje, jak wiele bajtów zostały faktycznie czytać (jest to interesujące, gdy plik ma co najmniej 50, ale mniej niż 60 bajtów). Jeśli plik ma mniej niż 50 bajtów, pojawi się EndOfStreamException.

+1

Masz na myśli aby zawsze sprawdzić zwracaną wartość Read i loop, jeśli to konieczne. Prawidłowe jest, aby Read zwrócił 1, nawet jeśli dostępnych jest kolejne 20000 bajtów. –

+0

Od FilStream.Read na MSDN: "Implementacja może zwrócić mniej bajtów niż żądano, nawet jeśli koniec strumienia nie został osiągnięty." –

+0

Ważne jest to, że dokumentacja wyraźnie zastrzegła to prawo: więc - nie robisz tego, nie śledzisz opublikowanego API –

1
using System.IO; 

public static byte[] ReadFile(string filePath) 
{ 
    byte[] buffer; 
    FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); 
    try 
    { 
     buffer = new byte[length];   // create buffer 
     fileStream.Read(buffer, 50, 10); 
    } 
    finally 
    { 
     fileStream.Close(); 
    } 
    return buffer; 
} 
+2

"Przesunięcie" w wywołaniu odczytu to przesunięcie ** w buforze **, a nie przesunięcie w strumieniu –

31

Tworzenie BinaryReader, czytać 10 bajtów zaczynając od bajtu 50:

byte[] test = new byte[10]; 
using (BinaryReader reader = new BinaryReader(new FileStream(file, FileMode.Open))) 
{ 
    reader.BaseStream.Seek(50, SeekOrigin.Begin); 
    reader.Read(test, 0, 10); 
} 
+1

Metoda Stream.Seek pobiera dwa argumenty. Powinien to być 'reader.BaseStream.Seek (50, SeekOrigin.Begin);' – Tajomaru

+0

Dobry połów, naprawiony. –

+1

najlepsza i najprostsza odpowiedź! dzięki – knocte

-3
byte[] a = new byte[60]; 
byte[] b = new byte[10]; 
Array.Copy(a ,50, b , 0 , 10); 
+0

-1: Q dotyczy odczytu bajtów z pliku * *. – Richard

+0

TYLKO dlatego, że edytowałeś pytanie ... W OP nie było to jasne. – Adrian

+0

Sugeruję, żebyś spojrzał na moją edycję. Wymagano pliku (i nie zmieniłem tytułu). – Richard

1

Można wykorzystać filestream się, a następnie zadzwonić czytać

string pathSource = @"c:\tests\source.txt"; 

using (FileStream fsSource = new FileStream(pathSource, 
    FileMode.Open, FileAccess.Read)) 
{ 

    // Read the source file into a byte array. 
    byte[] bytes = new byte[fsSource.Length]; 
    int numBytesToRead = 10; 
    int numBytesRead = 50; 
    // Read may return anything from 0 to numBytesToRead. 
    int n = fsSource.Read(bytes, numBytesRead, numBytesToRead); 
} 

Check this example MSDN

+0

numBytesRead jest offsetem, argumenty idą (bufor, przesunięcie, licznik) – oqx

+0

Masz rację, usuwając głos. – Richard

+0

dziękuję bardzo :) – oqx

2

Musisz :

  • dążyć do danych, które chcesz
  • wezwanie wielokrotnie Czytaj, sprawdzanie wartości zwracanej, dopóki masz wszystkie dane potrzebne

Na przykład:

public static byte[] ReadBytes(string path, int offset, int count) { 
    using(var file = File.OpenRead(path)) { 
     file.Position = offset; 
     offset = 0; 
     byte[] buffer = new byte[count]; 
     int read; 
     while(count > 0 && (read = file.Read(buffer, offset, count)) > 0) 
     { 
      offset += read; 
      count -= read; 
     } 
     if(count < 0) throw new EndOfStreamException(); 
     return buffer;  
    } 
}