কোনও ফাইল থেকে / মেমোরিস্ট্রিম সংরক্ষণ এবং লোড করুন


281

আমি একটি কাঠামোটিকে একটিতে সিরিয়ালাইজ করছি MemoryStreamএবং সিরিয়ালযুক্ত কাঠামোটি সংরক্ষণ এবং লোড করতে চাই।

সুতরাং, কিভাবে MemoryStreamএকটি ফাইল মধ্যে একটি সংরক্ষণ করুন এবং এটি ফাইল থেকে ফিরে লোড?


যদি আপনার কোনও ফাইল সংরক্ষণ করতে হয় তবে আপনি কেন ব্যবহার করছেন MemoryStream?
ওডে

@ ওডে আমার কী ব্যবহার করা উচিত? তুমি কি আমাকে একটা উদাহরণ দিতে পারবে?
মাহদী গিয়াসি

উত্তর:


365

আপনি অন্য স্ট্রমে মেমরি স্ট্রিমের বিষয়বস্তু লিখতে MemoryStream.WriteToবা ব্যবহার করতে পারেন Stream.CopyTo(ফ্রেমওয়ার্ক ভার্সন 4.5.2, 4.5.1, 4.5, 4) সমর্থন করে,

memoryStream.WriteTo(fileStream);

হালনাগাদ:

fileStream.CopyTo(memoryStream);
memoryStream.CopyTo(fileStream);

13
মেমরিস্ট্রিম.কপিটি আমার পক্ষে কাজ করবে বলে মনে হয় নি, যখন রাইটটো করেছে। আমার মনে হয় সম্ভবত এটি ছিল কারণ আমার স্মৃতিপ্রবাহ। অবস্থান 0 ছিল না
মার্ক অ্যাডামসন

10
হ্যা ঐটা সঠিক. তাদের মধ্যে পার্থক্য হ'ল রাইটটোটোর মতো ভিক্ষাবৃত্তির পরিবর্তে বর্তমান অবস্থানের পরিবর্তে কপিরটিও অনুলিপি করে।
আনোরজাকেন

6
[file|memory]Stream.Seek(0, SeekOrigin.Begin);পূর্বে যুক্ত করা CopyToবর্তমান অবস্থাকে 0 তে সেট করবে, যাতে CopyToএটি সম্পূর্ণ স্ট্রিমটি অনুলিপি করবে।
মার্টিন ব্যাক্যাশ

264

ধরে নিচ্ছি যে মেমরি স্ট্রিমের নাম ms

এই কোডটি একটি ফাইলে মেমরিস্ট্রিম লিখে রাখে:

using (FileStream file = new FileStream("file.bin", FileMode.Create, System.IO.FileAccess.Write)) {
   byte[] bytes = new byte[ms.Length];
   ms.Read(bytes, 0, (int)ms.Length);
   file.Write(bytes, 0, bytes.Length);
   ms.Close();
}

এবং এটি একটি মেমোরিস্ট্রিমে একটি ফাইল পড়ে:

using (MemoryStream ms = new MemoryStream())
using (FileStream file = new FileStream("file.bin", FileMode.Open, FileAccess.Read)) {
   byte[] bytes = new byte[file.Length];
   file.Read(bytes, 0, (int)file.Length);
   ms.Write(bytes, 0, (int)file.Length);
}

নেট ফ্রেমওয়ার্ক 4+ এ, আপনি কেবল ফাইল স্ট্রিমটিকে মেমোরিস্ট্রিমে অনুলিপি করতে পারেন এবং এটির মতো সহজ বিপরীতে:

MemoryStream ms = new MemoryStream();
using (FileStream file = new FileStream("file.bin", FileMode.Open, FileAccess.Read))
    file.CopyTo(ms);

এবং বিপরীত (মেমরি স্ট্রিম থেকে ফাইল স্ট্রিম):

using (FileStream file = new FileStream("file.bin", FileMode.Create, System.IO.FileAccess.Write))
    ms.CopyTo(file);

1
আমি জিজ্ঞাসা করতে পারি যে আপনি কেন ফাইলমোড ব্যবহার করেন? ফাইলমোড বনাম পড়ার নমুনায় কেন তৈরি করুন?
ফিল্টার

6
প্রথম কোড ব্লকে মেমরি স্ট্রিমটিকে ম্যানুয়ালি অনুলিপি করার পরিবর্তে অ্যারেতে অন্তর্নির্মিত ms.ToArray()ফাংশনটি ব্যবহার করতে পারেন ।
Gman

5
এমএস স্থাপন করা গুরুত্বপূর্ণ। অবস্থান = 0, অন্যথায় বাইট অ্যারে (এবং ফাইল) এ সমস্ত শূন্য থাকবে।
গ্রেগরি খ্রাপুনোভিচ

1
@ ফার্নানডো 68 এর নির্মাণের using (...){ }ঠিক একই প্রভাব রয়েছে।
ফ্যাব্রিকিও আরাউজো

2
ঠিক তেমনি 'ফাইল স্ট্রিম' এবং 'এমএস.কপিটিও (ফাইল)' ব্যবহার করে অন্যদের জন্য একটি সতর্কতা ফাইলের শেষ অবস্থানে অবস্থান নির্ধারণ করে এবং এরপরে আপনাকে স্মৃতি প্রবাহটি পুনরায় সেট করতে হবে।
রেবেকা

64

স্ট্রিমটি সত্যই নিষ্পত্তি করে এমনটি হওয়া উচিত এমনকি যদি এর ব্যতিক্রম হয় (ফাইল সম্ভবত I / O- তে সম্ভবত রয়েছে) - ক্লজগুলি ব্যবহার করা এটির জন্য আমার পছন্দসই পদ্ধতি, সুতরাং আপনার মেমোরিস্ট্রিম লেখার জন্য আপনি ব্যবহার করতে পারেন:

using (FileStream file = new FileStream("file.bin", FileMode.Create, FileAccess.Write)) {
    memoryStream.WriteTo(file);
}

এবং এটি আবার পড়ার জন্য:

using (FileStream file = new FileStream("file.bin", FileMode.Open, FileAccess.Read)) {
    byte[] bytes = new byte[file.Length];
    file.Read(bytes, 0, (int)file.Length);
    ms.Write(bytes, 0, (int)file.Length);
}

যদি ফাইলগুলি বড় হয়, তবে এটি লক্ষণীয় যে পঠন অপারেশন মোট ফাইলের আকারের দ্বিগুণ মেমরি ব্যবহার করবে । এর একটি সমাধান হ'ল বাইট অ্যারে থেকে মেমরিস্ট্রিম তৈরি করা - নিম্নলিখিত কোডটি ধরে নেওয়া হয় আপনি সেই স্ট্রিমটিতে লিখবেন না।

MemoryStream ms = new MemoryStream(bytes, writable: false);

আমার গবেষণা (নীচে) দেখায় যে অভ্যন্তরীণ বাফারটি আপনি যেমন পাস করেন ঠিক একই বাইট অ্যারে, তাই এটির স্মৃতি সংরক্ষণ করা উচিত।

byte[] testData = new byte[] { 104, 105, 121, 97 };
var ms = new MemoryStream(testData, 0, 4, false, true);
Assert.AreSame(testData, ms.GetBuffer());

41

সংক্ষিপ্ত সংস্করণগুলি খুঁজছেন এমন কারও জন্য:

var memoryStream = new MemoryStream(File.ReadAllBytes("1.dat"));

File.WriteAllBytes("1.dat", memoryStream.ToArray()); 

20

একটি ফাইল লেখার জন্য সম্মিলিত উত্তর হতে পারে;

MemoryStream ms = new MemoryStream();    
FileStream file = new FileStream("file.bin", FileMode.Create, FileAccess.Write);
ms.WriteTo(file);
file.Close();
ms.Close();

15

একটি ফাইলে সংরক্ষণ করুন

Car car = new Car();
car.Name = "Some fancy car";
MemoryStream stream = Serializer.SerializeToStream(car);
System.IO.File.WriteAllBytes(fileName, stream.ToArray());

একটি ফাইল থেকে লোড করুন

using (var stream = new MemoryStream(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
{
    public class Serializer
    {
        public static MemoryStream SerializeToStream(object o)
        {
            MemoryStream stream = new MemoryStream();
            IFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, o);
            return stream;
        }

        public static object DeserializeFromStream(MemoryStream stream)
        {
            IFormatter formatter = new BinaryFormatter();
            stream.Seek(0, SeekOrigin.Begin);
            object o = formatter.Deserialize(stream);
            return o;
        }
    }
}

মূলত এই শ্রেণীর বাস্তবায়ন এখানে পোস্ট করা হয়েছে

এবং

[Serializable]
public class Car
{
    public string Name;
}

14

একটি ফাইল লোড করার জন্য, আমি এটি অনেক ভাল পছন্দ করি

MemoryStream ms = new MemoryStream();
using (FileStream fs = File.OpenRead(file))
{
    fs.CopyTo(ms);
}

যদি মাইক্রোসফ্ট ওয়ার্ডে ফাইলটি খোলা থাকে - সেই ফাইলটি থেকে কোনও মেমরি স্ট্রিম তৈরি করার কোনও উপায় আছে? আমি একটি ত্রুটি পেয়েছি 'ফাইলটি অন্য প্রক্রিয়া দ্বারা ওপেন করা হয়েছে'
ফ্রেেনকিবি

@ ফ্রেঙ্কিবি আমিও এটি অনেকটা চালিয়েছি। আপনার যদি ওয়ার্ড বা অন্য কোনও অ্যাপে ফাইলটি খোলা থাকে তবে আপনি এটি করতে পারবেন না। ওয়ার্ডে কেবল ফাইলটি বন্ধ করুন।
ক্রিস্টোফার

@ ফ্রেঙ্কিবি আপনি কি ফাইল.কপি করতে পারবেন? আমি এটি খুঁজে পেয়েছি যে কাজ করতে হবে, তারপরে সেই ফাইলটি একটি স্ট্রিমে পড়ুন এবং নতুন ফাইলটি মুছুন ... ভয়ঙ্কর, তবে মনে হচ্ছে এটি কাজ করে।
উপহাস 2

3

আমি কোনও চিত্র যুক্ত করতে বা ভিডিও স্ট্রিম করার জন্য একটি প্যানেল নিয়ন্ত্রণ ব্যবহার করি তবে আপনি চিত্রটি এসকিউএল সার্ভারে চিত্র হিসাবে বা মাইএসকিউএলকে বৃহত্তর হিসাবে সংরক্ষণ করতে পারেন । এই কোডটি আমার পক্ষে অনেক কাজ করে। এটা দেখ.

এখানে আপনি ছবিটি সংরক্ষণ করুন

MemoryStream ms = new MemoryStream();
Bitmap bmp = new Bitmap(panel1.Width, panel1.Height);
panel1.DrawToBitmap(bmp, panel1.Bounds);
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); // here you can change the Image format
byte[] Pic_arr = new byte[ms.Length];
ms.Position = 0;
ms.Read(Pic_arr, 0, Pic_arr.Length);
ms.Close();

এবং এখানে আপনি লোড করতে পারেন, তবে আমি একটি পিকচারবক্স নিয়ন্ত্রণ ব্যবহার করেছি।

MemoryStream ms = new MemoryStream(picarr);
ms.Seek(0, SeekOrigin.Begin);
fotos.pictureBox1.Image = System.Drawing.Image.FromStream(ms);

আশা সাহায্য করে।


1
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;

namespace ImageWriterUtil
{
    public class ImageWaterMarkBuilder
    {
        //private ImageWaterMarkBuilder()
        //{
        //}
        Stream imageStream;
        string watermarkText = "©8Bytes.Technology";
        Font font = new System.Drawing.Font("Brush Script MT", 30, FontStyle.Bold, GraphicsUnit.Pixel);
        Brush brush = new SolidBrush(Color.Black);
        Point position;
        public ImageWaterMarkBuilder AddStream(Stream imageStream)
        {
            this.imageStream = imageStream;
            return this;
        }
        public ImageWaterMarkBuilder AddWaterMark(string watermarkText)
        {
            this.watermarkText = watermarkText;
            return this;
        }
        public ImageWaterMarkBuilder AddFont(Font font)
        {
            this.font = font;
            return this;
        }

        public ImageWaterMarkBuilder AddFontColour(Color color)
        {
            this.brush = new SolidBrush(color);
            return this;
        }
        public ImageWaterMarkBuilder AddPosition(Point position)
        {
            this.position = position;
            return this;
        }

        public void CompileAndSave(string filePath)
        {

            //Read the File into a Bitmap.
            using (Bitmap bmp = new Bitmap(this.imageStream, false))
            {
                using (Graphics grp = Graphics.FromImage(bmp))
                {


                    //Determine the size of the Watermark text.
                    SizeF textSize = new SizeF();
                    textSize = grp.MeasureString(watermarkText, font);

                    //Position the text and draw it on the image.
                    if (position == null)
                        position = new Point((bmp.Width - ((int)textSize.Width + 10)), (bmp.Height - ((int)textSize.Height + 10)));
                    grp.DrawString(watermarkText, font, brush, position);

                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        //Save the Watermarked image to the MemoryStream.
                        bmp.Save(memoryStream, ImageFormat.Png);
                        memoryStream.Position = 0;
                       // string fileName = Path.GetFileNameWithoutExtension(filePath);
                        // outPuthFilePath = Path.Combine(Path.GetDirectoryName(filePath), fileName + "_outputh.png");
                        using (FileStream file = new FileStream(filePath, FileMode.Create, System.IO.FileAccess.Write))
                        {
                            byte[] bytes = new byte[memoryStream.Length];
                            memoryStream.Read(bytes, 0, (int)memoryStream.Length);
                            file.Write(bytes, 0, bytes.Length);
                            memoryStream.Close();
                        }
                    }
                }
            }

        }
    }
}

ব্যবহার: -

ImageWaterMarkBuilder.AddStream(stream).AddWaterMark("").CompileAndSave(filePath);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.