मुझे उन सभी उत्तरों का उपयोग नहीं मिलता है CopyTo
, जहां शायद ऐप का उपयोग करने वाले सिस्टम को .NET 4.0+ में अपग्रेड नहीं किया गया है। मुझे पता है कि कुछ लोगों को अपग्रेड करने के लिए मजबूर करना चाहते हैं, लेकिन संगतता भी अच्छी है।
एक और बात, मुझे पहली जगह में दूसरी स्ट्रीम से कॉपी करने के लिए एक स्ट्रीम का उपयोग नहीं मिलता है। क्यों न करें:
byte[] bytes = myOtherObject.InputStream.ToArray();
एक बार आपके पास बाइट्स होने के बाद, आप उन्हें आसानी से एक फ़ाइल में लिख सकते हैं:
public static void WriteFile(string fileName, byte[] bytes)
{
string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
if (!path.EndsWith(@"\")) path += @"\";
if (File.Exists(Path.Combine(path, fileName)))
File.Delete(Path.Combine(path, fileName));
using (FileStream fs = new FileStream(Path.Combine(path, fileName), FileMode.CreateNew, FileAccess.Write))
{
fs.Write(bytes, 0, (int)bytes.Length);
//fs.Close();
}
}
यह कोड काम करता है क्योंकि मैंने इसे एक .jpg
फ़ाइल के साथ परीक्षण किया है , हालांकि मैं मानता हूं कि मैंने इसे केवल छोटी फ़ाइलों (1 एमबी से कम) के साथ उपयोग किया है। एक धारा, धाराओं के बीच कोई प्रतिलिपि नहीं, कोई एन्कोडिंग की आवश्यकता नहीं है, बस बाइट्स लिखें! StreamReader
यदि आपके पास पहले से ही एक स्ट्रीम है जिसके साथ आप bytes
सीधे सीधे रूपांतरित हो सकते हैं, तो अधिक जटिल चीज़ों की ज़रूरत नहीं है .ToArray()
!
केवल संभावित डाउनसाइड्स मैं इसे इस तरह से कर सकता हूं यदि आपके पास एक बड़ी फाइल है, तो इसे स्ट्रीम के रूप में रखना और बाइट सरणी का उपयोग करने और एक-एक करके बाइट्स पढ़ने के बजाय इसे स्ट्रीम करने .CopyTo()
या समतुल्य करने की अनुमति देता FileStream
है। यह धीमी गति से ऐसा कर सकता है, परिणामस्वरूप। लेकिन बाइट्स को लिखने .Write()
वाले FileStream
हैंडल की विधि के बाद से इसे चोक नहीं करना चाहिए , और यह केवल एक बार में एक बाइट कर रहा है, इसलिए यह मेमोरी को रोक नहीं पाएगा, सिवाय इसके कि आपके पास स्ट्रीम के रूप में स्ट्रीम रखने के लिए पर्याप्त मेमोरी होनी चाहिए byte[]
वस्तु । मेरी स्थिति में जहां मैंने इसका इस्तेमाल किया, एक होने के नाते OracleBlob
, मुझे एक में जाना पड़ा byte[]
, यह काफी छोटा था, और इसके अलावा, मेरे लिए कोई स्ट्रीमिंग उपलब्ध नहीं थी, वैसे भी, इसलिए मैंने बस अपने फाइट्स को अपने फंक्शन में भेजा, ऊपर।
एक अन्य विकल्प, एक स्ट्रीम का उपयोग करते हुए, इसे जॉन स्कीट के CopyStream
फ़ंक्शन के साथ उपयोग करना होगा जो कि किसी अन्य पोस्ट में था - यह सिर्फ FileStream
इनपुट स्ट्रीम लेने के लिए और सीधे से फाइल बनाने के लिए उपयोग करता है। यह उपयोग नहीं करता है File.Create
, जैसे उसने किया था (जो शुरू में मेरे लिए समस्याग्रस्त लग रहा था, लेकिन बाद में पाया गया कि यह संभवतः एक वीएस बग ...) था।
/// <summary>
/// Copies the contents of input to output. Doesn't close either stream.
/// </summary>
public static void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[8 * 1024];
int len;
while ( (len = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, len);
}
}
public static void WriteFile(string fileName, Stream inputStream)
{
string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
if (!path.EndsWith(@"\")) path += @"\";
if (File.Exists(Path.Combine(path, fileName)))
File.Delete(Path.Combine(path, fileName));
using (FileStream fs = new FileStream(Path.Combine(path, fileName), FileMode.CreateNew, FileAccess.Write)
{
CopyStream(inputStream, fs);
}
inputStream.Close();
inputStream.Flush();
}