Ich erhalte nicht alle Antworten mit CopyTo
, wobei die Systeme, die die App verwenden, möglicherweise nicht auf .NET 4.0+ aktualisiert wurden. Ich weiß, einige möchten die Leute zum Upgrade zwingen, aber die Kompatibilität ist auch gut.
Eine andere Sache ist, dass ich überhaupt keinen Stream verwende, um von einem anderen Stream zu kopieren. Warum nicht einfach machen:
byte[] bytes = myOtherObject.InputStream.ToArray();
Sobald Sie die Bytes haben, können Sie sie einfach in eine Datei schreiben:
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();
}
}
Dieser Code funktioniert so, wie ich ihn mit einer .jpg
Datei getestet habe , obwohl ich zugeben muss, dass ich ihn nur mit kleinen Dateien (weniger als 1 MB) verwendet habe. Ein Stream, kein Kopieren zwischen Streams, keine Codierung erforderlich, schreiben Sie einfach die Bytes! Sie müssen die Dinge nicht zu kompliziert machen, StreamReader
wenn Sie bereits einen Stream haben, in den Sie bytes
direkt konvertieren können .ToArray()
!
Die einzigen möglichen Nachteile, die ich auf diese Weise erkennen kann, sind, wenn Sie eine große Datei haben. Wenn Sie sie als Stream haben und sie verwenden .CopyTo()
oder gleichwertig verwenden, können Sie FileStream
sie streamen, anstatt ein Byte-Array zu verwenden und die Bytes einzeln zu lesen. Infolgedessen könnte es auf diese Weise langsamer sein. Es sollte jedoch nicht ersticken, da die .Write()
Methode der FileStream
Handles die Bytes schreibt, und es wird jeweils nur ein Byte ausgeführt, sodass der Speicher nicht verstopft wird, außer dass Sie über genügend Speicher verfügen müssen, um den Stream als zu speichern byte[]
Objekt . In meiner Situation, in der ich dies verwendet habe, OracleBlob
musste ich zu einem gehen byte[]
, es war klein genug, und außerdem stand mir sowieso kein Streaming zur Verfügung, also habe ich meine Bytes einfach an meine Funktion oben gesendet.
Eine andere Möglichkeit, einen Stream zu verwenden, besteht darin, ihn mit Jon Skeets CopyStream
Funktion zu verwenden, die sich in einem anderen Beitrag befand. Hiermit wird lediglich FileStream
der Eingabestream verwendet und die Datei direkt daraus erstellt. Es wird nicht verwendet File.Create
, wie er es tat (was anfangs für mich problematisch schien, aber später feststellte, dass es wahrscheinlich nur ein VS-Fehler war ...).
/// <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();
}