Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper way to read files asynchronously

I'm trying to read files asynchronously. I was wondering if this is a proper way to do so. Below is what I have tried so far. Is this correct?

static void Main(string[] args)
{
     Task<string> readFileTask = Task.Run(() => ReadFile(@"C:\Users\User\Desktop\Test.txt"));
     readFileTask.Wait();
     string astr = readFileTask.Result;
     Console.WriteLine(astr);
}

static private async Task<string> ReadFile(string filePath)
{
     string text = File.ReadAllText(filePath);
     return text;
}

Thanks.

like image 566
Trax Avatar asked Jan 12 '20 03:01

Trax


People also ask

How do you read asynchronous files?

For reading a file asynchronously there are two versions of read() method in the AsynchronousFileChannel class. read() method that returns a Future. read() method where you can pass CompletionHandler instance as an argument.

Which is the correct way to read the contents of a file asynchronously and display the contents in console in node using FS module?

Use fs. readFile() method to read the physical file asynchronously. Parameter Description: filename: Full path and name of the file as a string.

How do I read a node JS asynchronous file?

readFileSync() method is an inbuilt application programming interface of fs module which is used to read the file and return its content. In fs. readFile() method, we can read a file in a non-blocking asynchronous way, but in fs. readFileSync() method, we can read files in a synchronous way, i.e. we are telling node.

What are the three main patterns of asynchronous?

The three patterns discussed here are callbacks, promises, and async/await. There are other patterns as well as multiple variations of each so this post might expand in the future.


2 Answers

System.IO provides File.ReadAllTextAsync method for .Net Standard > 2.1 and .NET Core 2.0. If you are using C# 7.1 or higher you can use File.ReadAllTextAsync inside Main function directly.

static async Task Main(string[] args)
{
    var astr = await File.ReadAllTextAsync(@"C:\Users\User\Desktop\Test.txt");
    Console.WriteLine(astr);
}

Unfortunately, If you are not using C# 7.1 or higher then you can't use Async Main. You have to use Task.Run to calll async methods.

static void Main(string[] args)
{
    var astr=Task.Run(async () =>
    {
       return await File.ReadAllTextAsync(@"C:\Users\User\Desktop\Test.txt");
    }).GetAwaiter().GetResult();

    Console.WriteLine(astr);
 }

In case you are using .NET Framework then you have to use FileStream because System.IO not provides File.ReadAllTextAsync method.

private static async Task<string> ReadAllTextAsync(string filePath)  
{  
    using (FileStream sourceStream = new FileStream(filePath,  
        FileMode.Open, FileAccess.Read, FileShare.Read,  
        bufferSize: 4096, useAsync: true))  
    {  
        StringBuilder sb = new StringBuilder();  

        byte[] buffer = new byte[0x1000];  
        int numRead;  
        while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0)  
        {  
            string text = Encoding.Unicode.GetString(buffer, 0, numRead);  
            sb.Append(text);  
        }  

        return sb.ToString();  
     }  
}  
like image 103
habib Avatar answered Oct 08 '22 09:10

habib


As it has been said - you can use System.File.ReadAllTextAsync. But in case you need System.File.ReadAllTextAsync(string path) analog for .NET Framework, that is functionally closer to its .NET Core counterpart:

using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;

//...

static async Task<string> ReadAllTextAsync(string path)
{
    switch (path)
    {
        case "": throw new ArgumentException("Empty path name is not legal.", nameof(path));
        case null: throw new ArgumentNullException(nameof(path));
    }

    using var sourceStream = new FileStream(path, FileMode.Open, 
        FileAccess.Read, FileShare.Read, 
        bufferSize: 4096,
        useAsync: true);
    using var streamReader = new StreamReader(sourceStream, Encoding.UTF8, 
        detectEncodingFromByteOrderMarks: true); 
    // detectEncodingFromByteOrderMarks allows you to handle files with BOM correctly. 
    // Otherwise you may get chinese characters even when your text does not contain any

    return await streamReader.ReadToEndAsync();
}

// ...
like image 40
andrey_skulkin Avatar answered Oct 08 '22 09:10

andrey_skulkin