#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);
}
}
}