2009-06-04 3 views
9

Cho đến bây giờ tôi đang tính 12 LoC. Bạn có thể làm cho nó nhỏ hơn?Làm thế nào để sao chép một Dòng vào một mảng byte có mã C# nhỏ nhất?

using (Stream fileStream = File.OpenRead(fileName)) 
{ 
    using (BinaryReader binaryReader = new BinaryReader(fileStream)) 
    { 
     using (MemoryStream memoryStream = new MemoryStream()) 
     { 
      byte[] buffer = new byte[256]; 
      int count; 
      int totalBytes = 0; 
      while ((count = binaryReader.Read(buffer, 0, 256)) > 0) 
      { 
       memoryStream.Write(buffer, 0, count); 
       totalBytes += count; 
      } 
      memoryStream.Position = 0; 
      byte[] transparentPng = new byte[totalBytes]; 
      memoryStream.Read(transparentPng, 0, totalBytes); 
     } 
    } 
} 

Trả lời

30

Có một phương pháp tĩnh có thể làm điều này cho bạn trong một cuộc gọi.

var data = File.ReadAllBytes(fileName); 

Ngoài ra, một phương pháp mà làm việc cho bất kỳ Stream (trả về chiều dài của nó) sẽ là:

byte[] data; 
using (var br = new BinaryReader(stream)) 
    data = br.ReadBytes((int)stream.Length); 

Đối với suối mà không có một chiều dài được xác định rõ (ví dụ NetworkStream), và do đó nêu ra một ngoại lệ khi gọi stream.Length, điều này tất nhiên không hoạt động. Các giải pháp hơi phức tạp hơn trình bày trong câu trả lời của Jon Skeet là sau đó những gì bạn có thể muốn.

+5

Không phải tất cả các luồng đều trả về chiều dài của chúng mặc dù ... –

+0

data = binaryReader.ReadBytes (stream.Length); phải là data = br.ReadBytes (stream.Length); – OneSHOT

+0

Vâng, chúc mừng. Rõ ràng lỗi đánh máy. – Noldorin

27

Làm thế nào 'bout một:

byte[] result = File.ReadAllBytes(fileName); 
+0

+1 phút về trước :) –

+2

Mặc dù nó chỉ hoạt động cho các tập tin của khóa học ... nó phù hợp với mã trong câu hỏi ban đầu, nhưng không phải là tiêu đề của câu hỏi :) –

+0

Điểm tốt.Có lẽ nếu tôi cảm thấy buồn chán sau này, tôi sẽ diễn tả điều này theo một chức năng chấp nhận một luồng mở như đầu vào - cho tất cả các đoạn mã không ai làm phiền để đặt một chữ ký chức năng. –

8

Mặc dù không giảm LỘC (tôi chưa bao giờ sử dụng như một động lực chính), bạn có thể thu gọn usings như thế này:

using (Stream fileStream = File.OpenRead(fileName)) 
using (BinaryReader binaryReader = new BinaryReader(fileStream)) 
using (MemoryStream memoryStream = new MemoryStream()) 
{ 
    byte[] buffer = new byte[256]; 
    int count; 
    int totalBytes = 0; 
    while ((count = binaryReader.Read(buffer, 0, 256)) > 0) 
    { 
     memoryStream.Write(buffer, 0, count); 
     totalBytes += count; 
    } 
    memoryStream.Position = 0; 
    byte[] transparentPng = new byte[totalBytes]; 
    memoryStream.Read(transparentPng, 0, totalBytes);  
} 
+0

Bí quyết tuyệt vời, cảm ơn. –

+0

Bí quyết tuyệt vời với các câu lệnh sử dụng khác nhau –

+3

"tại sao điều đó lại quan trọng nếu nó hoạt động?" Nó không quan trọng miễn là bạn không phải duy trì mã ;-) – fretje

15

Giảm dòng code của bạn là khá đơn giản ở đây (trong khi vẫn làm việc với dòng tùy ý, thay vì chỉ files):

using (Stream fileStream = File.OpenRead(fileName)) 
using (MemoryStream memoryStream = new MemoryStream()) 
{ 
    int byteRead; 
    while ((byteRead = fileStream.ReadByte()) != -1) 
    { 
     memoryStream.WriteByte(byteRead); 
    } 
    return memoryStream.ToArray(); 
} 

Rõ ràng đó là một rất nhiều hiệu quả để đọc vào một bộ đệm hơn để đọc một byte tại một thời điểm, nhưng điều này làm giảm số lượng báo cáo (như bạn don không cần khai báo cả một bộ đệm một biến để giữ giá trị trả lại từ Luồng). Gọi số MemoryStream.ToArray() đơn giản hơn việc đọc vào một mảng mới được xây dựng.

Sử dụng bộ đệm đẹp hơn. Lưu ý rằng chúng tôi thực sự không cần BinaryReader:

using (Stream fileStream = File.OpenRead(fileName)) 
using (MemoryStream memoryStream = new MemoryStream()) 
{ 
    byte[] buffer = new byte[8192]; 
    int bytesRead; 
    while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     memoryStream.Write(buffer, 0, bytesRead); 
    } 
    return memoryStream.ToArray(); 
} 

Nếu bạn muốn trở thành thực sự tàn bạo, chúng ta có thể giảm số lượng các using báo cáo (với một trong hai giải pháp):

using (Stream fileStream = File.OpenRead(fileName), 
       memoryStream = new MemoryStream()) 
{ 
    byte[] buffer = new byte[8192]; 
    int bytesRead; 
    while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     memoryStream.Write(buffer, 0, bytesRead); 
    } 
    return ((MemoryStream)memoryStream).ToArray(); 
} 

Nhưng đó chỉ khó chịu :)

Tùy chọn khác tất nhiên là sử dụng thư viện như MiscUtil có phương thức đọc hoàn toàn từ luồng :) Phương pháp tiện ích có thể đơn giản như sau:

public static byte[] ReadFully(this Stream stream) 
{ 
    using (MemoryStream memoryStream = new MemoryStream()) 
    { 
     byte[] buffer = new byte[8192]; 
     int bytesRead; 
     while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0) 
     { 
      memoryStream.Write(buffer, 0, bytesRead); 
     } 
     return memoryStream.ToArray(); 
    } 
} 

Lưu ý rằng điều này không bao giờ đóng luồng - người gọi nên thực hiện điều đó.

2

Chỉ cần sử dụng các phương pháp CopyTo của Stream sao chép vào một MemoryStream, và nhận được các mảng:

using (var fileStream = File.OpenRead(fileName)) 
{ 
    using (var memoryStream = new MemoryStream()) 
    { 
     fileStream.CopyTo(memoryStream); 
     memoryStream.Seek(0, SeekOrigin.Begin); 

     byte[] transparentPng = memoryStream.ToArray(); 
    } 
}