Если вам нужно сохранить в файл, почему вы используете MemoryStream?
Одед
@Oded Что я должен использовать? Можете привести пример?
Махди Гиаси
Ответы:
365
Вы можете использовать MemoryStream.WriteToили Stream.CopyTo(поддерживается в версии 4.5.2, 4.5.1, 4.5, 4 фреймворка) методы для записи содержимого потока памяти в другой поток.
memoryStream.CopyTo, похоже, не работает для меня, в то время как WriteTo работал. Я думаю, возможно, это было, потому что моя memoryStream.Position не был 0
Марк Адамсон
10
Да, это правильно. Разница между ними заключается в том, что CopyTo копирует с любой текущей позиции, а не с самого начала, как WriteTo.
using (FileStream file =newFileStream("file.bin",FileMode.Create,System.IO.FileAccess.Write)){byte[] bytes =newbyte[ms.Length];
ms.Read(bytes,0,(int)ms.Length);
file.Write(bytes,0, bytes.Length);
ms.Close();}
и это читает файл в MemoryStream:
using (MemoryStream ms =newMemoryStream())
using (FileStream file =newFileStream("file.bin",FileMode.Open,FileAccess.Read)){byte[] bytes =newbyte[file.Length];
file.Read(bytes,0,(int)file.Length);
ms.Write(bytes,0,(int)file.Length);}
В .Net Framework 4+, вы можете просто скопировать FileStream в MemoryStream и выполнить обратную операцию так просто:
MemoryStream ms =newMemoryStream();
using (FileStream file =newFileStream("file.bin",FileMode.Open,FileAccess.Read))
file.CopyTo(ms);
И обратное (MemoryStream к FileStream):
using (FileStream file =newFileStream("file.bin",FileMode.Create,System.IO.FileAccess.Write))
ms.CopyTo(file);
Могу ли я спросить, почему вы используете FileMode.Create в примере чтения против FileMode.Open?
Philter
6
В первом блоке кода вместо ручного копирования потока памяти в массив вы можете использовать встроенную ms.ToArray()функцию.
Gman
5
Важно установить ms.Position = 0, иначе байтовый массив (и файл) будут содержать все нули.
Григорий Храпунович
1
@ Fernando68 конструкция using (...){ }имеет точно такой же эффект.
Fabricio Araujo
2
Так же, как предупреждение для других, «использование (FileStream» и «ms.CopyTo (файл)» устанавливает позицию в конец файла, и вам необходимо впоследствии сбросить поток памяти
Ребекка
64
Поток действительно должен быть удален, даже если есть исключение (вполне вероятно, для файлового ввода-вывода) - использование фраз - мой любимый подход для этого, поэтому для написания вашего MemoryStream вы можете использовать:
using (FileStream file =newFileStream("file.bin",FileMode.Create,FileAccess.Write)){
memoryStream.WriteTo(file);}
И для чтения назад:
using (FileStream file =newFileStream("file.bin",FileMode.Open,FileAccess.Read)){byte[] bytes =newbyte[file.Length];
file.Read(bytes,0,(int)file.Length);
ms.Write(bytes,0,(int)file.Length);}
Если файлы большие, то стоит отметить, что операция чтения будет использовать вдвое больше памяти, чем общий размер файла . Одним из решений этого является создание MemoryStream из байтового массива - следующий код предполагает, что вы не будете писать в этот поток.
MemoryStream ms =newMemoryStream(bytes, writable:false);
Мои исследования (ниже) показывают, что внутренний буфер - это тот же байтовый массив, который вы передаете ему, поэтому он должен экономить память.
byte[] testData =newbyte[]{104,105,121,97};var ms =newMemoryStream(testData,0,4,false,true);Assert.AreSame(testData, ms.GetBuffer());
Car car =newCar();
car.Name="Some fancy car";MemoryStream stream =Serializer.SerializeToStream(car);System.IO.File.WriteAllBytes(fileName, stream.ToArray());
Загрузить из файла
using (var stream =newMemoryStream(System.IO.File.ReadAllBytes(fileName))){Car car =(Car)Serializer.DeserializeFromStream(stream);}
где
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace Serialization{publicclassSerializer{publicstaticMemoryStreamSerializeToStream(object o){MemoryStream stream =newMemoryStream();IFormatter formatter =newBinaryFormatter();
formatter.Serialize(stream, o);return stream;}publicstaticobjectDeserializeFromStream(MemoryStream stream){IFormatter formatter =newBinaryFormatter();
stream.Seek(0,SeekOrigin.Begin);object o = formatter.Deserialize(stream);return o;}}}
Первоначально реализация этого класса была размещена здесь
Если файл открывается в Microsoft Word - есть ли способ создать поток памяти из этого файла? Я получаю сообщение об ошибке «файл открыт другим процессом»
FrenkyB
@FrenkyB Я тоже часто сталкиваюсь с этим. Если у вас есть файл, открытый в Word или другом приложении, вы не сможете это сделать. Просто закройте файл в Word.
Кристофер
@FrenkyB Можете ли вы сделать File.Copy? Я обнаружил, что это работает, затем прочитал из этого файла в поток и удалил новый файл ... ужасно, но, кажется, работает.
ridecar2
3
Я использую Panel Control для добавления изображения или даже потокового видео, но вы можете сохранить изображение на SQL Server как Image или MySQL как largeblob . Этот код работает для меня много. Проверьте это.
Здесь вы сохраняете изображение
MemoryStream ms =newMemoryStream();Bitmap bmp =newBitmap(panel1.Width, panel1.Height);
panel1.DrawToBitmap(bmp, panel1.Bounds);
bmp.Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg);// here you can change the Image formatbyte[]Pic_arr=newbyte[ms.Length];
ms.Position=0;
ms.Read(Pic_arr,0,Pic_arr.Length);
ms.Close();
И здесь вы можете загрузить, но я использовал PictureBox Control.
MemoryStream ms =newMemoryStream(picarr);
ms.Seek(0,SeekOrigin.Begin);
fotos.pictureBox1.Image=System.Drawing.Image.FromStream(ms);
MemoryStream
?Ответы:
Вы можете использовать
MemoryStream.WriteTo
илиStream.CopyTo
(поддерживается в версии 4.5.2, 4.5.1, 4.5, 4 фреймворка) методы для записи содержимого потока памяти в другой поток.Обновить:
источник
[file|memory]Stream.Seek(0, SeekOrigin.Begin);
beforeCopyTo
установит текущую позицию в 0, чтобыCopyTo
скопировать весь поток.Предполагая, что имя MemoryStream
ms
.Этот код записывает MemoryStream в файл:
и это читает файл в MemoryStream:
В .Net Framework 4+, вы можете просто скопировать FileStream в MemoryStream и выполнить обратную операцию так просто:
И обратное (MemoryStream к FileStream):
источник
ms.ToArray()
функцию.using (...){ }
имеет точно такой же эффект.Поток действительно должен быть удален, даже если есть исключение (вполне вероятно, для файлового ввода-вывода) - использование фраз - мой любимый подход для этого, поэтому для написания вашего MemoryStream вы можете использовать:
И для чтения назад:
Если файлы большие, то стоит отметить, что операция чтения будет использовать вдвое больше памяти, чем общий размер файла . Одним из решений этого является создание MemoryStream из байтового массива - следующий код предполагает, что вы не будете писать в этот поток.
Мои исследования (ниже) показывают, что внутренний буфер - это тот же байтовый массив, который вы передаете ему, поэтому он должен экономить память.
источник
Для тех, кто ищет короткие версии:
источник
Комбинированный ответ для записи в файл может быть;
источник
Сохранить в файл
Загрузить из файла
где
и
источник
Для загрузки файла мне это нравится намного лучше
источник
Я использую Panel Control для добавления изображения или даже потокового видео, но вы можете сохранить изображение на SQL Server как Image или MySQL как largeblob . Этот код работает для меня много. Проверьте это.
Здесь вы сохраняете изображение
И здесь вы можете загрузить, но я использовал PictureBox Control.
Надежда помогает.
источник
Использование :-
источник