需要一个异步文件读取器而不知道大小

发布于 2024-10-15 01:42:31 字数 243 浏览 11 评论 0原文

我需要一种异步将文件读取到字节数组的方法,但我不知道文件的大小(可能是几 Kb 或几 Mb)。

我尝试过 FileStream 来获取长度并使用 BeginRead,但问题是长度是 long 并且 BeginRead 只接受 int,如果文件太大,它可能会溢出。我想到的另一种方法是按较小的块读取它,但每次我必须读取新的字节块时,我都必须创建一个新数组(只是想避免必须初始化新的和更大的数组)。

我愿意接受更好或更简单的方法,否则我会分块阅读。

I need a method that reads a file to a byte array asynchronously but I don't know what size the file will be (it can be a few Kb of a good few Mb).

I've tried FileStream to get the length and use BeginRead, but the problem is length is a long and BeginRead only accepts int, if the file is to big it'll probably overflow. Another way I was thinking was read it by smaller chunks but every time I have to read a new chunk of bytes I'll have to create a new array (just wanted to avoid having to initialize new and bigger arrays).

I am open to better or simpler ways, otherwise I'll do it with the reading in smaller chunks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

谷夏 2024-10-22 01:42:31

您可以将其分块到 MemoryStream (MemoryStream将管理在内存中附加二进制信息),最后您只需调用 memoryStream.ToArray()

另外,这里有一种在两个流实例之间复制的方法(从文件流到 MemorySream:

如何将一个流的内容复制到另一个流?

You can chunk it into a MemoryStream (the MemoryStream will manage appending the binary information in memory) and at the end you can just call memoryStream.ToArray().

Also, here is a way to copy between two stream instances (from your file stream to your MemorySream:

How do I copy the contents of one stream to another?

橘虞初梦 2024-10-22 01:42:31

无论如何,你都必须分块阅读它,因为 .NET 不会支持大于 2Gb 的对象。

You'll have to read it by chunks anyway since .NET doesn't support objects larger than 2Gb.

半城柳色半声笛 2024-10-22 01:42:31

另一种方法是启动一个线程并调用 System.IO.File.ReadAllBytes(字符串)。听起来分块没有任何优势(因为你要把整个事情带入内存),所以这非常简单。

在此示例的帮助下:

    private void GetTheFile()
    {
        FileFetcher fileFetcher = new FileFetcher(Fetch);

        fileFetcher.BeginInvoke(@"c:\test.yap", new AsyncCallback(AfterFetch), null);
    }

    private void AfterFetch(IAsyncResult result)
    {
        AsyncResult async = (AsyncResult) result;

        FileFetcher fetcher = (FileFetcher)async.AsyncDelegate;

        byte[] file = fetcher.EndInvoke(result);

        //Do whatever you want with the file
        MessageBox.Show(file.Length.ToString());
    }

    public byte[] Fetch(string filename)
    {
        return File.ReadAllBytes(filename);
    }

Another way to do it would be to just spin up a thread and call System.IO.File.ReadAllBytes(string). It doesn't sound like there's any advantage to chunking (because you're going to bring the whole thing into memory) so this would be pretty straightforward.

With some help from this sample:

    private void GetTheFile()
    {
        FileFetcher fileFetcher = new FileFetcher(Fetch);

        fileFetcher.BeginInvoke(@"c:\test.yap", new AsyncCallback(AfterFetch), null);
    }

    private void AfterFetch(IAsyncResult result)
    {
        AsyncResult async = (AsyncResult) result;

        FileFetcher fetcher = (FileFetcher)async.AsyncDelegate;

        byte[] file = fetcher.EndInvoke(result);

        //Do whatever you want with the file
        MessageBox.Show(file.Length.ToString());
    }

    public byte[] Fetch(string filename)
    {
        return File.ReadAllBytes(filename);
    }
冰之心 2024-10-22 01:42:31

您可以在数组中指定一个偏移量,这将允许您分配一个大数组。

public IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)

stream.BeginRead(buffer, totalRead, chunkSize, ...);

然后在 EndRead 上,将读取大小添加到totalRead

You can specify an offset in your array which will allow you to allocate a single big array.

public IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)

stream.BeginRead(buffer, totalRead, chunkSize, ...);

Then on the EndRead, add the read size to totalRead

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文