सहेजें और एक फ़ाइल से MemoryStream लोड करें


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
MemoryStream.CopyTo ने मेरे लिए काम नहीं किया, जबकि WriteTo ने किया। मुझे लगता है कि शायद ऐसा इसलिए था क्योंकि मेरी मेमोरीस्ट्रीम.प्लस 0 नहीं थी
मार्क एडम्सन

10
हां यह सही है। उनके बीच का अंतर यह है कि CopyTo जो भी वर्तमान स्थिति की बजाय कॉपी से करता है वह हमेशा से है जैसे WriteTo करता है।
AnorZaken

6
[file|memory]Stream.Seek(0, SeekOrigin.Begin);पहले जोड़ने से CopyToवर्तमान स्थिति 0 पर सेट हो जाएगी, जिससे CopyToसंपूर्ण स्ट्रीम कॉपी हो जाएगी।
मार्टिन बैकशेक

264

यह मानते हुए कि MemoryStream नाम है ms

यह कोड MemoryStream को एक फ़ाइल में लिखता है:

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);
}

.Net फ्रेमवर्क 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
क्या मैं पूछ सकता हूँ कि आप फ़ाइल नमूना बनाम FileMode.Open में क्यों का उपयोग करते हैं?
फिलेर

6
पहले कोड ब्लॉक में, मैन्युअल रूप से मेमोरी स्ट्रीम को सरणी में कॉपी करने के बजाय, आप अंतर्निहित ms.ToArray()फ़ंक्शन का उपयोग कर सकते हैं ।
गमन

5
Ms.Position = 0 सेट करना महत्वपूर्ण है, अन्यथा बाइट सरणी (और फ़ाइल) में सभी शून्य होंगे।
ग्रेगरी ख़ारुनोविच

1
@ फर्नांडो 68 के निर्माण using (...){ }का ठीक वैसा ही प्रभाव है।
फैब्रियो एरुजो

2
बस दूसरों के लिए एक चेतावनी के रूप में (FileStream) और 'ms.CopyTo (फ़ाइल)' फ़ाइल की स्थिति के अंत को निर्धारित करता है और आपको मेमोरीस्ट्रीम को बाद में रीसेट करने की आवश्यकता होती है।
रेबेका

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);
}

यदि Microsoft Word में फ़ाइल खोली जाती है - क्या उस फ़ाइल से मेमोरी स्ट्रीम बनाने का कोई तरीका है? मुझे एक त्रुटि मिल रही है 'फ़ाइल एक अन्य प्रक्रिया द्वारा खोली गई है'
FrenkyB

@FrenkyB मैं भी इसमें बहुत दौड़ लगाता हूं। यदि आपके पास Word या किसी अन्य ऐप में फ़ाइल खुली है, तो आप ऐसा नहीं कर सकते। Word में फ़ाइल बंद करें।
क्रिस्टोफर

@FrenkyB क्या आप एक File.Copy कर सकते हैं? मैंने पाया है कि काम करना है, तो उस फ़ाइल से एक स्ट्रीम में पढ़ें और नई फ़ाइल को हटा दें ... भयानक, लेकिन काम करने लगता है।
१४

3

मैं एक छवि को जोड़ने या वीडियो को स्ट्रीम करने के लिए एक पैनल कंट्रोल का उपयोग करता हूं, लेकिन आप SQL सर्वर पर छवि या MySQL को लार्जबोल के रूप में सहेज सकते हैं । यह कोड मेरे लिए बहुत काम करता है। इसकी जांच - पड़ताल करें।

यहाँ आप इमेज को सेव करें

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);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.