Нужен асинхронный файл-ридер, не зная размера - PullRequest
2 голосов
/ 01 февраля 2011

Мне нужен метод, который асинхронно читает файл в байтовый массив, но я не знаю, какой размер будет у файла (это может быть несколько Кбайт из нескольких хороших Мб).

Я пробовал FileStream, чтобы получить длину и использовать BeginRead, но проблема в том, что длина длинная, и BeginRead принимает только int, если файл слишком большой, он, вероятно, переполнится. другой способ, которым я думал, был прочитать его меньшими порциями, но каждый раз, когда мне нужно читать новый кусок байтов, я должен был создавать новый массив (просто хотел избежать инициализации новых и больших массивов).

Если кто-нибудь знает какой-нибудь лучший способ или проще, я был бы счастлив и благодарен: P, в противном случае, я сделаю это с чтением небольшими кусками. Ты за любую помощь.

Ответы [ 4 ]

2 голосов
/ 01 февраля 2011

Вы можете разделить его на MemoryStream (MemoryStream будет управлять добавлением двоичной информации в память), и в конце вы можете просто вызвать memoryStream. ToArray () .

Кроме того, вот способ копирования между двумя экземплярами потока (из вашего файлового потока в ваш MemorySream:

Как скопировать содержимое одного потока в другой?

0 голосов
/ 01 февраля 2011

Другим способом сделать это было бы просто раскрутить поток и вызвать System.IO.File.ReadAllBytes (string) . Это не похоже на то, что есть какое-то преимущество для чанкинга (потому что вы собираетесь внести все это в память), так что это будет довольно просто.

С некоторой помощью из этого образца :

    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);
    }
0 голосов
/ 01 февраля 2011

Вам все равно придется читать его по частям, поскольку .NET не поддерживает объекты размером более 2 ГБ.

0 голосов
/ 01 февраля 2011

Вы можете указать offset в своем массиве, что позволит вам выделить один большой массив.

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

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

Затем в EndRead добавьте размер чтения в totalRead

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...