#region Copyright 2010-2014 by Roger Knapp, Licensed under the Apache License, Version 2.0 /* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #endregion using System; using System.Collections.Generic; using System.IO; using System.Text; using System.IO.Compression; namespace CSharpTest.Net.IO { /// /// A collection of Stream helpers /// public static class IOStream { /// Reads all of the bytes from the input stream, input stream will be disposed public static byte[] ReadAllBytes(Stream io) { using (io) using (MemoryStream ms = new MemoryStream()) { CopyStream(io, ms); return ms.ToArray(); } } /// Reads all of the bytes from the input stream, input stream will be disposed public static string ReadAllText(Stream io, Encoding encoding) { using (io) return encoding.GetString(ReadAllBytes(io)); } /// Reads a the number of bytes specified or throws IOException public static void Read(Stream io, byte[] bytes) { Read(io, bytes, bytes.Length); } /// Reads a the number of bytes specified or throws IOException public static byte[] Read(Stream io, int nBytes) { byte[] bytes = new byte[nBytes]; Read(io, bytes, nBytes); return bytes; } /// Reads a the number of bytes specified or throws IOException public static void Read(Stream io, byte[] bytes, int length) { if (length != ReadChunk(io, bytes, length)) throw new IOException(Resources.IOStreamFailedToRead); } /// Attempts to read the number of bytes specified and returns the actual count public static int ReadChunk(Stream io, byte[] bytes, int length) { return ReadChunk(io, bytes, 0, length); } /// Attempts to read the number of bytes specified and returns the actual count public static int ReadChunk(Stream io, byte[] bytes, int offset, int length) { int bytesRead = 0; int len = 0; while (length > bytesRead && 0 != (len = io.Read(bytes, bytesRead, length - bytesRead))) bytesRead += len; return bytesRead; } /// Copy the entire input stream to the provided output stream, input stream will be disposed /// The number of bytes copied public static long CopyStream(Stream input, Stream output) { using (input) return CopyStream(input, output, long.MaxValue); } /// Copy the specified number of bytes from the input stream to the provided output stream /// The number of bytes copied public static long CopyStream(Stream input, Stream output, long stopAfter) { byte[] bytes = new byte[ushort.MaxValue]; long bytesRead = 0; int len = 0; while (0 != (len = input.Read(bytes, 0, Math.Min(bytes.Length, (int)Math.Min(int.MaxValue, stopAfter - bytesRead))))) { output.Write(bytes, 0, len); bytesRead = bytesRead + len; } output.Flush(); return bytesRead; } /// Compress the existing file using an in-place replace. public static void Compress(string filename) { Compress(filename, filename); } /// Compress the existing file to the specified target. public static void Compress(string source, string target) { using (ReplaceFile replace = new ReplaceFile(target)) using (FileStream sourceStream = File.Open(source, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (Stream targetStream = replace.Create()) { if (sourceStream.Length != IOStream.Compress(sourceStream, targetStream)) throw new System.IO.IOException(Resources.IOStreamCompressionFailed); } sourceStream.Dispose(); replace.Commit(); } } /// Compress the contents of the source stream into the target stream. public static long Compress(Stream source, Stream target) { using (Stream gz = new GZipStream(target, CompressionMode.Compress, true)) return IOStream.CopyStream(source, gz); } /// Decompress the existing file using an in-place replace. public static void Decompress(string filename) { Decompress(filename, filename); } /// Decompress the existing file to the specified target. public static void Decompress(string source, string target) { using (ReplaceFile replace = new ReplaceFile(target)) using (FileStream sourceStream = File.Open(source, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (Stream targetStream = replace.Create()) IOStream.Decompress(sourceStream, targetStream); if (sourceStream.Length != sourceStream.Position) throw new System.IO.IOException(Resources.IOStreamCompressionFailed); sourceStream.Dispose(); replace.Commit(); } } /// Decompress the source stream to the specified target stream. public static long Decompress(Stream source, Stream target) { using (Stream gz = new GZipStream(source, CompressionMode.Decompress, true)) return IOStream.CopyStream(gz, target); } } }