Saya tidak mendapatkan semua jawaban menggunakan CopyTo
, di mana mungkin sistem yang menggunakan aplikasi mungkin belum ditingkatkan ke .NET 4.0+. Saya tahu beberapa orang ingin memaksa orang untuk melakukan upgrade, tetapi kompatibilitasnya juga bagus.
Hal lain, saya tidak bisa menggunakan aliran untuk menyalin dari aliran lain di tempat pertama. Mengapa tidak lakukan saja:
byte[] bytes = myOtherObject.InputStream.ToArray();
Setelah Anda memiliki byte, Anda dapat dengan mudah menuliskannya ke file:
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();
}
}
Kode ini berfungsi saat saya mengujinya dengan a .jpg
file, meskipun saya akui saya hanya menggunakannya dengan file kecil (kurang dari 1 MB). Satu aliran, tidak ada penyalinan antar aliran, tidak perlu penyandian, cukup tulis byte! Tidak perlu terlalu rumit hal-hal dengan StreamReader
jika Anda sudah memiliki aliran Anda dapat mengonversi bytes
secara langsung dengan .ToArray()
!
Hanya kerugian potensial yang dapat saya lihat dengan melakukannya dengan cara ini adalah jika ada file besar yang Anda miliki, menjadikannya sebagai stream dan menggunakan .CopyTo()
atau setara memungkinkan FileStream
untuk streaming itu daripada menggunakan array byte dan membaca byte satu per satu. Mungkin lebih lambat melakukannya dengan cara ini, sebagai hasilnya. Tetapi seharusnya tidak tersedak karena .Write()
metode FileStream
pegangan menulis byte, dan itu hanya melakukannya satu byte pada satu waktu, sehingga tidak akan menyumbat memori, kecuali bahwa Anda harus memiliki cukup memori untuk menahan aliran sebagai byte[]
objek . Dalam situasi saya di mana saya menggunakan ini, mendapatkan OracleBlob
, saya harus pergi ke byte[]
, itu cukup kecil, dan lagi pula, tidak ada streaming yang tersedia untuk saya, jadi saya hanya mengirim byte saya ke fungsi saya, di atas.
Pilihan lain, menggunakan aliran, akan menggunakannya dengan CopyStream
fungsi Jon Skeet yang ada di pos lain - ini hanya menggunakan FileStream
untuk mengambil aliran input dan membuat file dari itu secara langsung. Itu tidak digunakan File.Create
, seperti yang dia lakukan (yang awalnya tampak bermasalah bagi saya, tetapi kemudian menemukan itu kemungkinan hanya bug 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();
}