2016-03-02 10 views
13

Khuôn khổ .net có thư viện/lắp ráp tích hợp async cho phép làm việc với hệ thống tệp (ví dụ: File.ReadAllBytes, File.WriteAllBytes)?Khuôn khổ .net có cung cấp các phương thức không đồng bộ để làm việc với hệ thống tệp không?

Hoặc tôi có phải viết thư viện của riêng mình bằng cách sử dụng phương thức asyncStreamReaderStreamWriter không?

Something như thế này sẽ là khá đẹp:

var bytes = await File.ReadAllBytes("my-file.whatever"); 

Trả lời

13

Liệu các khung lưới có một async built-in thư viện/lắp ráp cho phép làm việc với các hệ thống tập tin

Yes. Có các phương thức không đồng bộ để làm việc với hệ thống tệp nhưng không phải cho các phương thức trợ giúp trên loại tĩnh File. Họ đang ở trên FileStream.

Vì vậy, không có File.ReadAllBytesAsync nhưng có FileStream.ReadAsync, vv Ví dụ:

byte[] result; 
using (FileStream stream = File.Open(@"C:\file.txt", FileMode.Open)) 
{ 
    result = new byte[stream.Length]; 
    await stream.ReadAsync(result, 0, (int)stream.Length); 
} 
+0

Nếu tệp bạn đã tuần tự hóa thành luồng byte lớn (3gb +) thì có thể cho rằng độ dài luồng sẽ lớn hơn loại int có thể lưu trữ và khiến nó tràn không? – Dave

+1

@Đã có thể. Trong những trường hợp như vậy, bạn có thể cần phải đọc theo khối. – i3arnon

+0

Bạn nên có logic để đọc theo khối bất kể. Theo [tài liệu của Microsoft] (https://docs.microsoft.com/en-us/dotnet/api/system.io.filestream.readasync?view=netframework-4.7.1#System_IO_FileStream_ReadAsync_System_Byte___System_Int32_System_Int32_System_Threading_CancellationToken_), ReadAsync không được bảo đảm để lấp đầy toàn bộ mảng. Bạn cần phải kiểm tra giá trị trả về để xem giá trị _actually_ đã đọc. – Phil

11

Nó đã thực hiện điều đó. Xem ví dụ Using Async for File Access bài viết MSDN.

private async Task WriteTextAsync(string filePath, string text) 
{ 
    byte[] encodedText = Encoding.Unicode.GetBytes(text); 

    using (FileStream sourceStream = new FileStream(filePath, 
     FileMode.Append, FileAccess.Write, FileShare.None, 
     bufferSize: 4096, useAsync: true)) 
    { 
     await sourceStream.WriteAsync(encodedText, 0, encodedText.Length); 
    }; 
} 
-7

Nếu bạn phải viết một tập tin trong một nhiệm vụ nền bạn có thể viết nó sincronously trong một phương pháp async.

static void Main(string[] args) 
{ 
    Console.WriteLine("1"); 
    // thread 1, sync 
    byte[] dataToWrite = System.Text.ASCIIEncoding.ASCII.GetBytes("my custom data"); 
    Task.Run(() => 
    { 
     Console.WriteLine("2"); 
     // aspetto un secondo 
     System.Threading.Thread.Sleep(1000); 
     // thread 2, async code 
     System.IO.File.WriteAllBytes(@"c:\temp\prova.txt", dataToWrite); 
     Console.WriteLine("2, end"); 
    }); 

    Console.WriteLine("3, exit"); 

    Console.ReadLine(); 
    // thread 1 
} 

sản lượng thi công sẽ là: 1,3,2,2 cuối

+5

Đây không phải là không đồng bộ và là một lời khuyên rất xấu. – i3arnon

+0

Bạn không chờ đợi nhiệm vụ đó. Ngoài ra, đó là hầu như không sử dụng IOCP – MickyD

+0

lý do tại sao nó không phải là không đồng bộ xin lỗi? Nó có thể được sử dụng nếu bạn phải viết trong nền mà không cần phải chờ đợi kết thúc viết –

4

Liệu các khung lưới có một async built-in thư viện/lắp ráp cho phép làm việc với các hệ thống tập tin (ví dụ: File.ReadAllBytes, File.WriteAllBytes)?

Thật không may, các API dành cho máy tính để bàn hơi bị lỗi khi nói đến các hoạt động tệp không đồng bộ. Như bạn đã lưu ý, một số phương pháp tiện lợi tốt đẹp không có tương đương không đồng bộ. Còn thiếu là không đồng bộ mở tệp (đặc biệt hữu ích khi mở tệp qua chia sẻ mạng).

Tôi hy vọng các API này sẽ được thêm khi thế giới di chuyển sang .NET Core.

Hoặc tôi có phải viết thư viện của riêng mình bằng các phương pháp không đồng bộ của StreamReader và StreamWriter không?

Đó là cách tiếp cận tốt nhất ngay bây giờ.

Lưu ý rằng khi sử dụng ReadAsync/WriteAsync và bạn bè, bạn phải rõ ràng mở tệp để truy cập không đồng bộ. Cách duy nhất để thực hiện việc này (hiện tại) là sử dụng quá tải hàm khởi tạo FileStream có thông số bool isAsync (chuyển true) hoặc thông số FileOptions (qua FileOptions.Asynchronous). Vì vậy, bạn không thể sử dụng các phương thức mở tiện lợi như File.Open.

+1

Cảm ơn thông tin đó và đặc biệt là: 'FileOptions.Asynchronous' cảm ơn bạn! 'isAsync' dường như bị xóa. +1 – BendEg

Các vấn đề liên quan