Хобрук: Ваш путь к мастерству в программировании

Как написать список байтовых массивов в файл С#

У меня есть загрузчик, который я использую для разделения файлов и загрузки их на мой сервер sql. Затем я загружаю каждый фрагмент и создаю временный файл. Я пытаюсь записать список байтовых массивов (байт []) в один файл, чтобы воссоздать этот файл. Это связано с тем, что когда я пытаюсь прочитать список массивов байтов в один массив, я получаю исключение OutOfMemory. Мне просто интересно, как лучше всего это сделать. Спасибо!

 string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        int currentRowSelection = fUS_FileDataGridView.CurrentCell.RowIndex;
        var totalNumber = fUS_FileDataGridView.Rows[currentRowSelection].Cells[6].Value;
        for (int i = 1; i < 149; i++)
        {
            using (var stream1 = new FileStream(path + @"\" + i + ".zip", FileMode.Open, FileAccess.Read))
            {
                using (var reader = new BinaryReader(stream1))
                {
                    list_.Add(reader.ReadBytes((int)stream1.Length));
                    stream1.Close();
                    stream1.Dispose();
                    reader.Close();
                    reader.Dispose();

                }
            }
        }
        //array_ = list_.SelectMany(a => a).ToArray();

        filePaths_ = @"C:\Users\ATLAS\Desktop\13\fun.zip";
        foreach (byte[] bytes in list_)
        {
            var doc = System.Text.Encoding.Default.GetString(bytes);
            string textToAdd1 = bytes.ToString();
            try
            {
                using (FileStream fs = File.Create(filePaths_))
                using (StreamWriter writer = new StreamWriter(fs, Encoding.Default, 512))
                {
                    writer.Write(textToAdd1);
                    writer.Close();
                    writer.Dispose();
                }
            }
            finally
            {
            }
        }
    }

Обновление: мой вопрос отличается от других, которые я нашел, потому что я не могу поместить свой список байтовых массивов в один массив для записи файла. В настоящее время я получаю только файл размером 1 КБ из своего кода, где я должен получить файл размером 100 КБ.

Обновление 2: приведенный ниже код имеет гораздо больше смысла, но теперь я получаю сообщение об ошибке «поток не доступен для записи».

filePaths_ = @"C:\Users\ATLAS\Desktop\13\fun.zip";
        using (FileStream fs = File.Create(filePaths_))
        for (int i = 0; i < 151; i++)
        {
            using (var stream1 = new FileStream(path + @"\" + i + ".zip", FileMode.Open, FileAccess.Read))
            {
                using (var reader = new BinaryReader(stream1))
                {
                    using (StreamWriter writer = new StreamWriter(fs, Encoding.Default, 512))
                    {
                        writer.Write(reader);
                    }
                }
            }
        } 


Ответы:


1

Если проблема заключается в нехватке памяти, вам следует подумать о том, как уменьшить объем используемой памяти.

Я не знаю, каковы ваши требования, но на основе предоставленного вами кода вы можете сделать все записи внутри своего первого цикла foreach. Таким образом, вы загружаете только один файл за раз, и GC освобождает память, как только вы закончите работу с каждым файлом.

    using (FileStream fs = File.AppendText(filePaths_)) 
    {
        for (int i = 1; i < 149; i++)
        {
            using (var stream1 = new FileStream(path + @"\" + i + ".zip", FileMode.Open, FileAccess.Read))
            {
                using (var reader = new BinaryReader(stream1))
                {
                    //list_.Add(reader.ReadBytes((int)stream1.Length));
                    //Instead of adding that to list, write them to disk here
                    //fs.Write(...)
                    //...


                    stream1.Close();//No need for this, using is going to call it. 
                    stream1.Dispose();//No need for this, using is going to call it. 
                    reader.Close();//No need for this, using is going to call it. 
                    reader.Dispose();//No need for this, using is going to call it. 

                }
            }
        } 
     }
04.08.2016
  • Все файлы объединяются в один файл, using (FileStream fs = File.Create(filePaths_)) должен быть вне цикла for. 04.08.2016
  • Я использовал приведенный выше код, и у меня не было исключения из памяти, но я получил только файл размером 1 КБ (должен быть намного больше). Я посмотрю на это немного больше (уже смотрю на это в течение трех дней) и вернусь к вам, ребята. Спасибо! 04.08.2016
  • @TWelles1 вы получаете файл размером 1 КБ, потому что используете bytes[].ToString(). у вас уже есть реальное строковое значение массива байтов в вашей переменной документа, которую вы должны использовать 04.08.2016

  • 2

    Если я правильно понимаю, что вы хотите:

    // Fill list_
    List<byte[]> list_ = null;
    // ....
    
    string filePaths_ = @"C:\Users\ATLAS\Desktop\13\fun.zip";
    // Create FileStream and BinaryWriter
    using (var fs = File.OpenWrite(filePaths_)){
        using (var bw = new BinaryWriter(fs)){
            foreach (var bytes in list_)
                bw.Write(bytes); // Write each byte array to the stream
        }
    }
    

    Обновлено. Вы можете сделать это лучше, прямо скопировав один поток в другой:

    string filePaths_ = @"C:\Users\ATLAS\Desktop\13\fun.zip";
    // Result FileStream and BinaryWriter
    using (var fs = File.OpenWrite(filePaths_))
    {
        for (int i = 1; i < 149; i++)
        {
            using (var stream1 = new FileStream(path + @"\" + i + ".zip", FileMode.Open, FileAccess.Read))
            {
                // Just copy stream1 to fs
                stream1.CopyTo(fs);
            }
        }
    }
    
    04.08.2016

    3

    Похоже, что вы действительно хотите сделать, это добавить каждый массив байтов в существующий файл. Поэтому я думаю, что в то время, когда вы хотите записать каждый отдельный массив в файл, вы просто откроете файловый поток, используя FileMode.Append (вместо FileMode.Open).

    04.08.2016
    Новые материалы

    Я собираюсь научить вас Python шаг за шагом
    Привет, уважаемый энтузиаст Python! 👋 Готовы погрузиться в мир Python? Сегодня я приготовил для вас кое-что интересное, что сделает ваше путешествие более приятным, чем шарик мороженого в..

    Альтернатива шаблону исходящих сообщений для архитектуры микросервисов
    Познакомьтесь с двухэтапным сообщением В этой статье предлагается альтернативный шаблон для папки Исходящие : двухэтапное сообщение. Он основан не на очереди сообщений, а на..

    React on Rails
    Основное приложение Reverb - это всеми любимый монолит Rails. Он отлично обслуживает наш API и уровень просмотра трафика. По мере роста мы добавляли больше интерактивных элементов..

    Что такое гибкие методологии разработки программного обеспечения
    Что представляют собой гибкие методологии разработки программного обеспечения в 2023 году Agile-методологии разработки программного обеспечения заключаются в следующем: И. Введение A...

    Ториго  — революция в игре Го
    Наш следующий вызов против ИИ и для ИИ. Сможет ли он победить людей в обновленной игре Го? Обратите внимание, что в следующей статье AI означает искусственный интеллект, а Goban  —..

    Простое развертывание моделей с помощью Mlflow — Упаковка классификатора обзоров продуктов NLP от HuggingFace
    Как сохранить свои модели машинного обучения в формате с открытым исходным кодом с помощью MLFlow, чтобы позже получить возможность легкого развертывания. Сегодня модели упаковки имеют несколько..

    Математика и интуиция - Часть 1
    У каждой математической формулы есть доказательство. Часто эти доказательства слишком сложно понять, поскольку многие из них основаны на индукции, некоторые - на очень сложных наблюдениях, а..