How do I convert a WaveStream to a Byte Array using NAudio?
public static class StreamExtension
{
public static byte[] ToArray(this Stream stream)
{
byte[] buffer = new byte[4096];
int reader = 0;
MemoryStream memoryStream = new MemoryStream();
while ((reader = stream.Read(buffer, 0, buffer.Length)) != 0)
memoryStream.Write(buffer, 0, reader);
return memoryStream.ToArray();
}
}
You can try this vision and should work for you, try it
MemoryStream memoryStr = new MemoryStream();
while ((read = stream.Read(buffer, 0, buffer.Length)) != 0)
memoryStr.Write(buffer, 0, read );
You use it like a System.IO.Stream.
Use the Read Method. But remember. If you convert the whole stream into ONE Bytearray it could cause and OutOfMemoryException. It depends on how big the stream is. But you could use something like this:
byte[] buffer = new byte[stream.Length];
int read = stream.Read(buffer, 0, buffer.Length);
Related
I have a C# function that receives a compressed ByteArray as a parameter.
I need to EXTRACT this byteArray and send the resulting uncompressed byteArray to another function.
I need help extracting zipBytes to unzippedBytes please see below PSEUDO CODE:
SOLUTION using Zlib.net!
byte[] receiveZipByte (byte[] zipBytes)
{
MemoryStream oInStream = new MemoryStream(pZFileData);
ZInputStream oZInstream = new ZInputStream(oInStream);
MemoryStream oOutStream = new MemoryStream();
byte[] buffer = new byte[2000];
int len;
while ((len = oZInstream.read(buffer, 0, 2000)) > 0)
{
oOutStream.Write(buffer, 0, len);
}
byte[] pFileData = oOutStream.ToArray();
oZInstream.Close();
oOutStream.Close();
return unzippedBytes;
}
If what you're trying to do is decompress data that has been compressed using zlib, I would suggest using the ZLib.NET library: http://www.componentace.com/zlib_.NET.htm
It would depend on what you want to do with the data; but, here's an example of using a Stream with DotNetZip:
using (var input = new ZipInputStream(new MemoryStream(zipBytes)))
{
ZipEntry e;
while ((e = input.GetNextEntry()) != null)
{
if (e.IsDirectory) continue;
using (var output = File.Open(e.FileName, FileMode.Create, FileAccess.ReadWrite))
{
while ((n = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, n);
}
}
}
}
I am trying to download a file to my computer and in the same time save it to Byte Array:
try
{
var req = (HttpWebRequest)HttpWebRequest.Create(url);
var fileStream = new FileStream(filePath,
FileMode.Create, FileAccess.Write, FileShare.Write);
using (var resp = req.GetResponse())
{
using (var stream = resp.GetResponseStream())
{
byte[] buffer = new byte[0x10000];
int len;
while ((len = stream.Read(buffer, 0, buffer.Length)) > 0)
{
//Do with the content whatever you want
// ***YOUR CODE***
MemoryStream memoryStream = new MemoryStream();
if (len > 0)
{
memoryStream.Write(buffer, 0, len);
len = stream.Read(buffer, 0, buffer.Length);
}
file = memoryStream.ToArray();
fileStream.Write(buffer, 0, len);
}
}
}
fileStream.Close();
}
catch (Exception exc) { }
And i noticed that it's not download all the file with this.
I wan to do it because i want to download a file and in the same time work with it.
Any idea why this problem happen?
There is a much easier way to get the file bytes by using the System.Net.WebClient.WebClient():
private static byte[] DownloadFile(string absoluteUrl)
{
using (var client = new System.Net.WebClient())
{
return client.DownloadData(absoluteUrl);
}
}
Usage:
var bytes = DownloadFile(absoluteUrl);
The problem looks to be double-reading - you are putting different things into the memory-stream / file-stream - it should be more like:
// declare file/memory stream here
while ((len = stream.Read(buffer, 0, buffer.Length)) > 0)
{
memoryStream.Write(buffer, 0, len);
fileStream.Write(buffer, 0, len);
// if you need to process "len" bytes, do it here
}
You might be able to lose "memoryStream" completely if you are processing the "len" bytes immediately. If it fits in-memory, it may be easier to just use WebClient.DownloadData and then File.WriteAllBytes.
i'm implementing a wcf service that accepts image streams. however i'm currently getting an exception when i run it. as its trying to get the length of the stream before the stream is complete. so what i'd like to do is buffer the stream until its complete. however i cant find any examples of how to do this...
can anyone help?
my code so far:
public String uploadUserImage(Stream stream)
{
Stream fs = stream;
BinaryReader br = new BinaryReader(fs);
Byte[] bytes = br.ReadBytes((Int32)fs.Length);// this causes exception
File.WriteAllBytes(filepath, bytes);
}
Rather than try to fetch the length, you should read from the stream until it returns that it's "done". In .NET 4, this is really easy:
// Assuming we *really* want to read it into memory first...
MemoryStream memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
memoryStream.Position = 0;
File.WriteAllBytes(filepath, memoryStream);
In .NET 3.5 there's no CopyTo method, but you can write something similar yourself:
public static void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, bytesRead);
}
}
However, now we've got something to copy a stream, why bother reading it all into memory first? Let's just write it straight to a file:
using (FileStream output = File.OpenWrite(filepath))
{
CopyStream(stream, output); // Or stream.CopyTo(output);
}
I'm not sure what you are returning (or not returning), but something like this might work for you:
public String uploadUserImage(Stream stream) {
const int KB = 1024;
Byte[] bytes = new Byte[KB];
StringBuilder sb = new StringBuilder();
using (BinaryReader br = new BinaryReader(stream)) {
int len;
do {
len = br.Read(bytes, 0, KB);
string readData = Encoding.UTF8.GetString(bytes);
sb.Append(readData);
} while (len == KB);
}
//File.WriteAllBytes(filepath, bytes);
return sb.ToString();
}
A string can hold up to 2 GB, I believe.
Try this :
using (StreamWriter sw = File.CreateText(filepath))
{
stream.CopyTo(sw);
sw.Close();
}
Jon Skeets answer for .Net 3.5 and below using a Buffer Read is actually done incorrectly.
The buffer isn't cleared between reads which can result in issues on any read that returns less than 8192, for example if the 2nd read, read 192 bytes, the 8000 last bytes from the first read would STILL be in the buffer which would then be returned to the stream.
My code below you supply it a Stream and it will return a IEnumerable array.
Using this you can for-each it and Write to a MemoryStream and then use .GetBuffer() to end up with a compiled merged byte[].
private IEnumerable<byte[]> ReadFullStream(Stream stream) {
while(true) {
byte[] buffer = new byte[8192];//since this is created every loop, its buffer is cleared
int bytesRead = stream.Read(buffer, 0, buffer.Length);//read up to 8192 bytes into buffer
if (bytesRead == 0) {//if we read nothing, stream is finished
break;
}
if(bytesRead < buffer.Length) {//if we read LESS than 8192 bytes, resize the buffer to essentially remove everything after what was read, otherwise you will have nullbytes/0x00bytes at the end of your buffer
Array.Resize(ref buffer, bytesRead);
}
yield return buffer;//yield return the buffer data
}//loop here until we reach a read == 0 (end of stream)
}
I have the following constructor method which opens a MemoryStream from a file path:
MemoryStream _ms;
public MyClass(string filePath)
{
byte[] docBytes = File.ReadAllBytes(filePath);
_ms = new MemoryStream();
_ms.Write(docBytes, 0, docBytes.Length);
}
I need to change this to accept a Stream instead of a file path. Whats the easiest/most efficient way to get a MemoryStream from the Stream object?
In .NET 4, you can use Stream.CopyTo to copy a stream, instead of the home-brew methods listed in the other answers.
MemoryStream _ms;
public MyClass(Stream sourceStream)
_ms = new MemoryStream();
sourceStream.CopyTo(_ms);
}
Use this:
var memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
This will convert Stream to MemoryStream.
If you're modifying your class to accept a Stream instead of a filename, don't bother converting to a MemoryStream. Let the underlying Stream handle the operations:
public class MyClass
{
Stream _s;
public MyClass(Stream s) { _s = s; }
}
But if you really need a MemoryStream for internal operations, you'll have to copy the data out of the source Stream into the MemoryStream:
public MyClass(Stream stream)
{
_ms = new MemoryStream();
CopyStream(stream, _ms);
}
// Merged From linked CopyStream below and Jon Skeet's ReadFully example
public static void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[16*1024];
int read;
while((read = input.Read (buffer, 0, buffer.Length)) > 0)
{
output.Write (buffer, 0, read);
}
}
You can simply do:
var ms = new MemoryStream(File.ReadAllBytes(filePath));
Stream position is 0 and ready to use.
You will have to read in all the data from the Stream object into a byte[] buffer and then pass that into the MemoryStream via its constructor. It may be better to be more specific about the type of stream object you are using. Stream is very generic and may not implement the Length attribute, which is rather useful when reading in data.
Here's some code for you:
public MyClass(Stream inputStream) {
byte[] inputBuffer = new byte[inputStream.Length];
inputStream.Read(inputBuffer, 0, inputBuffer.Length);
_ms = new MemoryStream(inputBuffer);
}
If the Stream object doesn't implement the Length attribute, you will have to implement something like this:
public MyClass(Stream inputStream) {
MemoryStream outputStream = new MemoryStream();
byte[] inputBuffer = new byte[65535];
int readAmount;
while((readAmount = inputStream.Read(inputBuffer, 0, inputBuffer.Length)) > 0)
outputStream.Write(inputBuffer, 0, readAmount);
_ms = outputStream;
}
I use this combination of extension methods:
public static Stream Copy(this Stream source)
{
if (source == null)
return null;
long originalPosition = -1;
if (source.CanSeek)
originalPosition = source.Position;
MemoryStream ms = new MemoryStream();
try
{
Copy(source, ms);
if (originalPosition > -1)
ms.Seek(originalPosition, SeekOrigin.Begin);
else
ms.Seek(0, SeekOrigin.Begin);
return ms;
}
catch
{
ms.Dispose();
throw;
}
}
public static void Copy(this Stream source, Stream target)
{
if (source == null)
throw new ArgumentNullException("source");
if (target == null)
throw new ArgumentNullException("target");
long originalSourcePosition = -1;
int count = 0;
byte[] buffer = new byte[0x1000];
if (source.CanSeek)
{
originalSourcePosition = source.Position;
source.Seek(0, SeekOrigin.Begin);
}
while ((count = source.Read(buffer, 0, buffer.Length)) > 0)
target.Write(buffer, 0, count);
if (originalSourcePosition > -1)
{
source.Seek(originalSourcePosition, SeekOrigin.Begin);
}
}
How do I copy the contents of one stream to another?
see that. accept a stream and copy to memory. you should not use .Length for just Stream because it is not necessarily implemented in every concrete Stream.
public static void Do(Stream in)
{
_ms = new MemoryStream();
byte[] buffer = new byte[65536];
while ((int read = input.Read(buffer, 0, buffer.Length))>=0)
_ms.Write (buffer, 0, read);
}
byte[] fileData = null;
using (var binaryReader = new BinaryReader(Request.Files[0].InputStream))
{
fileData = binaryReader.ReadBytes(Request.Files[0].ContentLength);
}
I'm trying to compress and decompress a memory stream to send it over an tcp connection.
In the following code snap I do do the decompressing right after compressing to get it working first.
What ever I do I end up with a devompressed buffer wit all zero's and in the line
int read = Decompress.Read(buffie, 0, buffie.Length);
it seems that 0 bytes are read.
Does anyone has a clue what is wrong?
bytesRead = ms.Read(buf, 0, i);
MemoryStream partialMs = new MemoryStream();
GZipStream gZip = new GZipStream(partialMs, CompressionMode.Compress);
gZip.Write(buf, 0, buf.Length);
partialMs.Position = 0;
byte[] compressedBuf = new byte[partialMs.Length];
partialMs.Read(compressedBuf, 0, (int)partialMs.Length);
partialMs.Close();
byte[] gzBuffer = new byte[compressedBuf.Length + 4];
System.Buffer.BlockCopy(compressedBuf, 0, gzBuffer, 4, compressedBuf.Length);
System.Buffer.BlockCopy(BitConverter.GetBytes(buf.Length), 0, gzBuffer, 0, 4);
using (MemoryStream mems = new MemoryStream())
{
int msgLength = BitConverter.ToInt32(gzBuffer, 0);
byte[] buffie = new byte[msgLength];
mems.Write(gzBuffer, 4, gzBuffer.Length - 4);
mems.Flush();
mems.Position = 0;
using (GZipStream Decompress = new GZipStream(mems, CompressionMode.Decompress, true))
{
int read = Decompress.Read(buffie, 0, buffie.Length);
Decompress.Close();
}
}
Your implementation could use some work. there seems to be some confusion as to which streams should be used where. here is a working example to get you started..
see user content at the bottom of this MSDN page
var original = new byte[65535];
var compressed = GZipTest.Compress(original);
var decompressed = GZipTest.Decompress(compressed);
using System.IO;
using System.IO.Compression;
public class GZipTest
{
public static byte[] Compress(byte[] uncompressedBuffer)
{
using (var ms = new MemoryStream())
{
using (var gzip = new GZipStream(ms, CompressionMode.Compress, true))
{
gzip.Write(uncompressedBuffer, 0, uncompressedBuffer.Length);
}
byte[] compressedBuffer = ms.ToArray();
return compressedBuffer;
}
}
public static byte[] Decompress(byte[] compressedBuffer)
{
using (var gzip = new GZipStream(new MemoryStream(compressedBuffer), CompressionMode.Decompress))
{
byte[] uncompressedBuffer = ReadAllBytes(gzip);
return uncompressedBuffer;
}
}
private static byte[] ReadAllBytes(Stream stream)
{
var buffer = new byte[4096];
using (var ms = new MemoryStream())
{
int bytesRead = 0;
do
{
bytesRead = stream.Read(buffer, 0, buffer.Length);
if (bytesRead > 0)
{
ms.Write(buffer, 0, bytesRead);
}
} while (bytesRead > 0);
return ms.ToArray();
}
}
}
You're not closing the GzipStream you're writing to, so it's probably all buffered. I suggest you close it when you're done writing your data.
By the way, you can get the data out of a MemoryStream much more easily than your current code: use MemoryStream.ToArray.