Je n'obtiens pas toutes les réponses en utilisant CopyTo
, où peut-être que les systèmes utilisant l'application n'ont peut-être pas été mis à niveau vers .NET 4.0+. Je sais que certains voudraient forcer les gens à mettre à niveau, mais la compatibilité est également très bien aussi.
Une autre chose, je n'utilise pas un flux pour copier à partir d'un autre flux en premier lieu. Pourquoi ne pas simplement faire:
byte[] bytes = myOtherObject.InputStream.ToArray();
Une fois que vous avez les octets, vous pouvez facilement les écrire dans un fichier:
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();
}
}
Ce code fonctionne comme je l'ai testé avec un .jpg
fichier, mais j'avoue ne l'avoir utilisé qu'avec de petits fichiers (moins de 1 Mo). Un flux, pas de copie entre les flux, aucun encodage nécessaire, il suffit d'écrire les octets! Pas besoin de trop compliquer les choses StreamReader
si vous avez déjà un flux avec lequel vous pouvez convertir bytes
directement .ToArray()
!
Seuls les inconvénients potentiels que je peux voir en procédant de cette façon sont s'il y a un gros fichier que vous possédez, l'avoir comme flux et utiliser .CopyTo()
ou équivalent permet FileStream
de le diffuser au lieu d'utiliser un tableau d'octets et de lire les octets un par un. En conséquence, cela pourrait être plus lent à faire de cette façon. Mais il ne devrait pas s'étouffer puisque la .Write()
méthode des FileStream
poignées écrivant les octets, et il ne le fait qu'un octet à la fois, donc il n'encombrera pas la mémoire, sauf que vous devrez avoir suffisamment de mémoire pour contenir le flux en tant que byte[]
objet . Dans ma situation où j'utilisais cela, obtenir un OracleBlob
, je devais aller à un byte[]
, c'était assez petit, et en plus, il n'y avait pas de streaming disponible pour moi, de toute façon, alors j'ai juste envoyé mes octets à ma fonction, ci-dessus.
Une autre option, en utilisant un flux, serait de l'utiliser avec la CopyStream
fonction de Jon Skeet qui était dans un autre post - cela permet simplement FileStream
de prendre le flux d'entrée et de créer le fichier directement à partir de celui-ci. Il n'utilise pas File.Create
, comme il l'a fait (ce qui au départ semblait être problématique pour moi, mais a trouvé plus tard que c'était probablement juste un 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();
}