Não recebo todas as respostas usando CopyTo , onde talvez os sistemas que usam o aplicativo talvez não tenham sido atualizados para o .NET 4.0+. Sei que alguns gostariam de forçar as pessoas a atualizar, mas a compatibilidade também é boa.
Outra coisa, eu não uso um fluxo para copiar de outro fluxo em primeiro lugar. Por que não fazer:
byte[] bytes = myOtherObject.InputStream.ToArray();
Depois de ter os bytes, você pode gravá-los facilmente em um arquivo:
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();
}
}
Esse código funciona como eu testei com um .jpgarquivo, embora admita que o usei apenas com arquivos pequenos (menos de 1 MB). Um fluxo, sem copiar entre fluxos, sem necessidade de codificação, basta escrever os bytes! Não há necessidade de complicar demais as coisas StreamReaderse você já tiver um fluxo com o qual possa converter bytesdiretamente .ToArray()!
Somente possíveis desvantagens que posso ver dessa maneira é que se você tiver um arquivo grande, tê-lo como um fluxo e usar .CopyTo()ou equivalente permite FileStreamtransmiti-lo em vez de usar uma matriz de bytes e ler os bytes um a um. Como resultado, pode ser mais lento fazê-lo dessa maneira. Mas não deve engasgar, já que o .Write()método dos FileStreammanipuladores escreve os bytes e apenas o executa um byte de cada vez, para que não obstrua a memória, exceto que você terá que ter memória suficiente para manter o fluxo como um byte[]objeto . Na minha situação em que usei isso, obtendo um OracleBlob, tive que ir para um byte[], era pequeno o suficiente e, além disso, não havia streaming disponível para mim, de qualquer maneira, então acabei de enviar meus bytes para minha função acima.
Outra opção, usando um fluxo, seria usá-lo com a CopyStreamfunção de Jon Skeet que estava em outro post - isso apenas usa FileStreamo fluxo de entrada e cria o arquivo diretamente dele. Ele não usa File.Create, como ele fez (o que inicialmente parecia problemático para mim, mas depois descobriu que provavelmente era apenas um bug do 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();
}