Обработка ввода файлового потока C # в цикле WHILE, вызывающая ошибку времени выполнения - PullRequest
3 голосов
/ 05 марта 2012

У меня есть консольное приложение C #, которое я пытаюсь создать, которое обрабатывает все файлы в заданном каталоге и записывает вывод в другой заданный каталог. Я хочу обрабатывать входные файлы по X байтов за раз.

namespace FileConverter
{
    class Program
    {
        static void Main(string[] args)
        {
            string srcFolder = args[0];  
            string destFolder = args[1];   
            string[] srcFiles = Directory.GetFiles(srcFolder);
            for (int s = 0; s < srcFiles.Length; s++)
            {
                byte[] fileBuffer;
                int numBytesRead = 0;
                int readBuffer = 10000;
                FileStream srcStream = new FileStream(srcFiles[s], FileMode.Open, FileAccess.Read);
                int fileLength = (int)srcStream.Length;

                string destFile = destFolder + "\\" + Path.GetFileName(srcFiles[s]) + "-processed";
                FileStream destStream = new FileStream(destFile, FileMode.OpenOrCreate, FileAccess.Write);

                //Read and process the source file by some chunk of bytes at a time
                while (numBytesRead < fileLength)
                {
                    fileBuffer = new byte[readBuffer];

                    //Read some bytes into the fileBuffer
                    //TODO: This doesn't work on subsequent blocks
                    int n = srcStream.Read(fileBuffer, numBytesRead, readBuffer);

                    //If we didn't read anything, there's no more to process
                    if (n == 0)
                        break;

                    //Process the fileBuffer
                    for (int i = 0; i < fileBuffer.Length; i++)
                    {
                        //Process each byte in the array here
                    }
                    //Write data
                    destStream.Write(fileBuffer, numBytesRead, readBuffer);
                    numBytesRead += readBuffer;
                }
                srcStream.Close();
                destStream.Close();
            }
        }
    }
}

Я сталкиваюсь с ошибкой во время выполнения в:

//Read some bytes into the fileBuffer
//TODO: This doesn't work on subsequent blocks
int n = srcStream.Read(fileBuffer, numBytesRead, readBuffer);

Я не хочу загружать весь файл в память, так как он может иметь размер в несколько гигабайт. Я действительно хочу иметь возможность прочитать некоторое количество байтов, обработать их, записать их в файл, а затем прочитать следующие байты X и повторить.

Он проходит одну итерацию цикла, а затем умирает на второй. Я получаю ошибку:

"Смещение и длина вышли за пределы массива или счетчика больше, чем количество элементов от индекса до конца исходной коллекции."

Пример файла, с которым я работаю, составляет около 32 КБ.

Может кто-нибудь сказать мне, что я здесь делаю не так?

Ответы [ 2 ]

8 голосов
/ 05 марта 2012

Второй параметр для чтения - это не смещение в файле - это смещение в буфере , с которого начинается запись данных. Так что просто пройдите 0.

Кроме того, не думайте, что буфер заполнен каждый раз: вы должны обрабатывать только «n» байтов из буфера. И буфер должен быть повторно использован между итерациями.

Если вам нужно прочитать точно количество байтов:

static void ReadOrThrow(Stream source, byte[] buffer, int count) {
     int read, offset = 0;
     while(count > 0 && (read = source.Read(buffer, offset, count)) > 0) {
        offset += read;
        count -= read;
    }
    if(count != 0) throw new EndOfStreamException();
}

Обратите внимание, что запись работает аналогично, поэтому вам нужно передать 0 в качестве смещения и n в качестве счетчика.

0 голосов
/ 05 марта 2012

Это должно быть

destStream.Write(fileBuffer, numBytesRead, n);
numBytesRead += n;

, потому что n - это фактическое число прочитанных байтов

...