ฉันไม่ได้รับคำตอบทั้งหมดที่ใช้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 MB) สตรีมเดียวไม่มีการคัดลอกระหว่างสตรีมไม่จำเป็นต้องเข้ารหัสเพียงเขียนไบต์! ไม่จำเป็นต้องทำสิ่งที่ยุ่งยากเกินไปStreamReader
หากคุณมีกระแสคุณสามารถแปลงเป็นbytes
โดยตรงด้วย.ToArray()
!
ข้อเสียที่เป็นไปได้เท่านั้นที่ฉันเห็นในการทำเช่นนี้คือถ้าคุณมีไฟล์ขนาดใหญ่การใช้เป็นสตรีมและการใช้.CopyTo()
หรือเทียบเท่าอนุญาตให้FileStream
สตรีมแทนการใช้อาร์เรย์ไบต์และอ่านไบต์ทีละรายการ อาจทำให้การทำแบบนี้ช้าลง แต่มันไม่ควรทำให้หายใจไม่ออกเนื่องจาก.Write()
วิธีการของการFileStream
จัดการการเขียนไบต์และมันทำเพียงหนึ่งไบต์ในแต่ละครั้งดังนั้นมันจะไม่เกิดการอุดตันหน่วยความจำยกเว้นว่าคุณจะต้องมีหน่วยความจำเพียงพอที่จะถือกระแสเป็นbyte[]
วัตถุ ในสถานการณ์ของฉันที่ฉันใช้สิ่งนี้การรับOracleBlob
ฉันต้องไปbyte[]
มันเล็กพอและนอกจากนี้ไม่มีการส่งกระแสข้อมูลให้ฉันดังนั้นฉันเพิ่งส่งไบต์ไปยังฟังก์ชันของฉันข้างต้น
ตัวเลือกอื่นที่ใช้สตรีมคือใช้กับCopyStream
ฟังก์ชั่นของ Jon Skeet ที่อยู่ในโพสต์อื่น - นี่ใช้FileStream
เพื่อรับสตรีมอินพุตและสร้างไฟล์จากมันโดยตรง มันไม่ได้ใช้งานFile.Create
เหมือนที่เขาทำ (ซึ่งตอนแรกดูเหมือนจะเป็นปัญหาสำหรับฉัน แต่ภายหลังพบว่ามันอาจเป็นเพียงข้อผิดพลาด VS ... )
/// <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();
}