CopyTo
Uygulamayı kullanan sistemlerin .NET 4.0+ sürümüne yükseltilmemiş olabileceği tüm yanıtları kullanmıyorum . Bazılarının insanları yükseltmeye zorlamak istediğini biliyorum, ancak uyumluluk da güzel.
Başka bir şey, öncelikle başka bir akıştan kopyalamak için bir akış kullanmıyorum. Neden sadece:
byte[] bytes = myOtherObject.InputStream.ToArray();
Baytları aldıktan sonra, bunları bir dosyaya kolayca yazabilirsiniz:
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();
}
}
Bu kod bir .jpg
dosya ile test ettik gibi çalışır , ancak ben sadece küçük dosyalarla (1 MB'den az) kullandığımı itiraf ediyorum. Bir akış, akışlar arasında kopyalama yok, kodlamaya gerek yok, sadece baytları yazın! StreamReader
Zaten bytes
doğrudan dönüştürebileceğiniz bir akışınız varsa, şeyleri aşırı karmaşıklaştırmanıza gerek yok .ToArray()
!
Bu şekilde yaparken görebildiğim sadece potansiyel dezavantajları, sahip olduğunuz büyük bir dosya varsa, bir akış olarak sahip olmak .CopyTo()
ya da eşdeğerini FileStream
kullanmak, bir bayt dizisi kullanmak ve baytları tek tek okumak yerine onu akışa izin verir . Sonuç olarak, bu şekilde yapmak daha yavaş olabilir. Ancak baytları yazma tutamaçlarının .Write()
yöntemi boğulmamalı FileStream
ve her seferinde sadece bir bayt yapıyor, bu nedenle belleği tıkamayacak, ancak akışı bir tutmak için yeterli belleğe sahip olmanız gerekecek byte[]
nesne . Bunu kullandığım durumumda, bir almak OracleBlob
zorunda kaldım, gitmek zorunda kaldım byte[]
, yeterince küçüktü ve ayrıca, yine de benim için kullanılabilir bir akış yoktu, bu yüzden baytlarımı yukarıdaki işleve gönderdim.
Bir akışı kullanan başka bir seçenek, onu CopyStream
başka bir gönderideki Jon Skeet işleviyle kullanmak olacaktır - bu sadece FileStream
giriş akışını almak ve dosyayı doğrudan oluşturmak için kullanır . Kullanamadığı File.Create
gibi kullanmaz (başlangıçta benim için sorunlu görünüyordu, ancak daha sonra muhtemelen sadece bir VS hatası olduğunu buldu ...).
/// <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();
}