Saving MemoryStream to File produces 0 bytes - c#

I'm using this code to write an MP3 MemoryStream to file:
using (var nSpeakStreamAsMp3 = new MemoryStream())
using (var nWavFileReader = new WaveFileReader(nSpeakStream))
using (var nMp3Writer = new LameMP3FileWriter(nSpeakStreamAsMp3, nWavFileReader.WaveFormat, LAMEPreset.STANDARD_FAST))
{
nWavFileReader.CopyTo(nMp3Writer);
string sPath = "C:\\inetpub\\wwwroot\\server\\bin\\mymp3.mp3";
using (FileStream nFile = new FileStream(sPath, FileMode.Create, System.IO.FileAccess.Write))
{
nSpeakStreamAsMp3.CopyTo(nFile);
}
sRet = (String.Concat("data:audio/mpeg;base64,", Convert.ToBase64String(nSpeakStreamAsMp3.ToArray())));
}
return sRet;
For some reason which I don't see, this produces a file of 0 bytes.
However, the MP3 stream is valid and does work. I'm passing it as a Base64String to a website, and I do hear it.
Where might be the error here?

nSpeakStreamAsMp3 is currently positioned at the end of the stream; you need to think like a VCR: be kind, rewind (nSpeakStreamAsMp3.Position = 0;) before you copy the value out again
make sure you flush nMp3Writer; if possible, close nMp3Writer completely

Related

C#: Barcode to byte array to valid zip file

I'm scaning a Pdf417 barcode which returns me a byte[] array. The DataString itself is a cryptic value like face to keyboard multiple times and fast. So I'm guessing it could be a zip file which is stored in the barcode. In the zip file there should be a xml file.
I had different attempts so far to convert my byte[] array to a valid zip file. In the end I was never able to open said zip file.
The barcodes are created by certified software solutions, so the barcode is not the problem for sure.
I can't be the only one who has had this problem, right?
Output when reading a barcode with dummy data in it:
"\0\0\0\vz\0\u0002B\u0001\u0002PK\u0003\u0004\n\0\0\0\b\0 E\u0081Q|\u0015\u00163Î\u0001\0\0\u0004\u0004\0\0\u0004\0\0\0txab}SMo£0\u0010½ï¯°|\a\u001bª¤Ý\u0015Påc\u0093Fê&\b²9ôÆÂ$ \r¦²M\u0093üûNø\b$Që\u008bí7ï½\u0019{lçù\u0098ïÉ\aH\u0095\u0015Â¥\u0096É)\u0001\u0011\u0017I&v.ý»\u009e\u0019OôÙsÖ\u0004iB¹4Õúý\u0017c\u0087ÃÁT\u0087L©\u0004b3N\u0099\u008aSÈ#¦\u0012fs>ä6·X\u0018í#y\u009aB\u008cS¤Ñ}}\u001c\u008d)\t\u0017S\u0097ÎV+\\u009dÔ¦^z?\b\u000egRäï\u00918\u0091\u0097À\b&Æ2ÊÁ¥/\u0091Pä\u000fd ÉhNÉÛÂwé\u0013ç\u009c²Fäcé\u0085XLÉk¤´¨4\u0015\u009d\u0092Y&[äìÒ\u0017×ÚJ\u001fn\u008cQh,¥÷8\u0018\u009a\u0016\u000eÓÆa>ütØ%Tgbmªf\u001fö\0\u0094\u0015I\aTàV\u0016¹gãe\u0018|`pËa\u0015pÍ)\u0085Îö5ɲ\u008d\a$ÕHgÍn½\u009d\u0005ö'\ao\u0080'á&ç\u000ek\u0080\u008e1\u0093Ø>\u0018\u0083\u0080m¦\u0015ëEV:\u0005Ù\u0006njYÃQ{ãB\u0094ÊaÕú:\u001c\u0096¹g]r\u009ew½"¿ðuæ²Pª©ox\u0011÷Ñ\u008e;ÞÌ\u008dWß7&\u0085Ð2ûW\u009e\u001fÍM\r\u0001ìJ|Oxa\u008dS\v\ÓüRÆi¤ ª·â]\u0090^Íßçs\u0096 Û\u009b~lm:¬ãM!)ã³v¤Ã\u0002Óô²Þ\u0087:Ù$\u008dä\u000eTPî\u0081ÝÃ7\aú½Ý\u0002\u001a}\QÙ\u001d·nï×Ý\u000fð\u0093Êÿí×aø\u0082±ÓÞ'PK\u0001\u0002\u0014\0\n\0\0\0\b\0 E\u0081Q|\u0015\u00163Î\u0001\0\0\u0004\u0004\0\0\u0004\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0txabPK\u0005\u0006\0\0\0\0\u0001\0\u0001\02\0\0\0ð\u0001\0\0\0\0"
Dont pay too much attention to this function, at this stage I'm probably trying too much to get to a solution. This is just one of many test voids of mine.
public void Test(byte[] bytes)
{
byte[] zipBytes;
using (var memoryStream = new MemoryStream())
{
using (var zipArchive = new ZipArchive(memoryStream, ZipArchiveMode.Create, leaveOpen: true))
{
var zipEntry = zipArchive.CreateEntry("test");
using (Stream entryStream = zipEntry.Open())
{
entryStream.Write(bytes, 0, bytes.Length);
}
}
zipBytes = memoryStream.ToArray();
}
using (var fileStream = new FileStream(#"C:\BarcodeReaderTesting\test.zip", FileMode.OpenOrCreate))
{
fileStream.Write(zipBytes, 0, zipBytes.Length);
}
}
Any tips on this topic?

Deflatestream - end of stream reached before parsing was completed

I try to write a List to a FileStream. Since the object was too big, I split the list in evenly distributed chunks, and append it to the FileStream with a DeflateStream to compress the data. This all works fine.
However if I try to do the same to decompress it, it gives an error: 'reached the end of the stream before parsing was completed'. This is the code to decompress:
using (FileStream fs = new FileStream(filePath, FileMode.Open)) {
using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Decompress, true)) {
//Deserialize offerte
BinaryFormatter bf = new BinaryFormatter();
//Check position
while (ds.BaseStream.Position < ds.BaseStream.Length) {
result.AddRange((List<User>)bf.Deserialize(ds));
}
}
}
What I notice is that the first chunk of users is nicely being written to result. However when it should start on the second chunk of users it gives an error right away (It seems before even trying to get the second chunk). What can I do about this or is wrong?
#Edit 10:43 - 16-10-2015 Additional remark
If I skip the DeflateStream and only use FileStream, then it works like a charm.
Compress method (I call this function x times, every chunk once):
using (FileStream fs = new FileStream(filePath, FileMode.Append)) {
using (DeflateStream cs = new DeflateStream(fs, CompressionMode.Compress)) {
//Serialize offerte
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(cs, offerte);
}
}

Copy MemoryStream to FileStream and save the file?

I don't understand what I'm doing wrong here. I generate couple of memory streams and in debug-mode I see that they are populated. But when I try to copy MemoryStream to FileStream in order to save the file fileStream is not populated and file is 0bytes long (empty).
Here is my code
if (file.ContentLength > 0)
{
var bytes = ImageUploader.FilestreamToBytes(file); // bytes is populated
using (var inStream = new MemoryStream(bytes)) // inStream is populated
{
using (var outStream = new MemoryStream())
{
using (var imageFactory = new ImageFactory())
{
imageFactory.Load(inStream)
.Resize(new Size(320, 0))
.Format(ImageFormat.Jpeg)
.Quality(70)
.Save(outStream);
}
// outStream is populated here
var fileName = "test.jpg";
using (var fileStream = new FileStream(Server.MapPath("~/content/u/") + fileName, FileMode.CreateNew, FileAccess.ReadWrite))
{
outStream.CopyTo(fileStream); // fileStream is not populated
}
}
}
}
You need to reset the position of the stream before copying.
outStream.Position = 0;
outStream.CopyTo(fileStream);
You used the outStream when saving the file using the imageFactory. That function populated the outStream. While populating the outStream the position is set to the end of the populated area. That is so that when you keep on writing bytes to the steam, it doesn't override existing bytes. But then to read it (for copy purposes) you need to set the position to the start so you can start reading at the start.
If your objective is simply to dump the memory stream to a physical file (e.g. to look at the contents) - it can be done in one move:
System.IO.File.WriteAllBytes(#"C:\\filename", memoryStream.ToArray());
No need to set the stream position first either, since the .ToArray() operation explicitly ignores that, as per #BaconBits comment below https://learn.microsoft.com/en-us/dotnet/api/system.io.memorystream.toarray?view=netframework-4.7.2.
Another alternative to CopyTo is WriteTo.
Advantage:
No need to reset Position.
Usage:
outStream.WriteTo(fileStream);
Function Description:
Writes the entire contents of this memory stream to another stream.

Read a PDF into a string or byte[] and write that string/byte[] back to disk

I am having a problem in my app where it reads a PDF from disk, and then has to write it back to a different location later.
The emitted file is not a valid PDF anymore.
In very simplified form, I have tried reading/writing it using
var bytes = File.ReadAllBytes(#"c:\myfile.pdf");
File.WriteAllBytes(#"c:\output.pdf", bytes);
and
var input = new StreamReader(#"c:\myfile.pdf").ReadToEnd();
File.WriteAllText("c:\output.pdf", input);
... and about 100 permutations of the above with various encodings being specified. None of the output files were valid PDFs.
Can someone please lend a hand? Many thanks!!
In C#/.Net 4.0:
using (var i = new FileStream(#"input.pdf", FileMode.Open, FileAccess.Read))
using (var o = File.Create(#"output.pdf"))
i.CopyTo(o);
If you insist on having the byte[] first:
using (var i = new FileStream(#"input.pdf", FileMode.Open, FileAccess.Read))
using (var ms = new MemoryStream())
{
i.CopyTo(ms);
byte[] rawdata = ms.GetBuffer();
using (var o = File.Create(#"output.pdf"))
ms.CopyTo(o);
}
The memory stream may need to be ms.Seek(0, SeekOrigin.Origin) or something like that before the second CopyTo. look it up, or try it out
You're using File.WriteAllText to write your file out.
Try File.WriteAllBytes.

GZipStream only decompresses first line

My GZipStream will only decompress the first line of the file. Extracting the contents via 7-zip works as expected and gives me the entire file contents. It also extracts as expected using gunzip on cygwin and linux, so I expect this is O/S specific (Windows 7).
I'm not certain how to go about troubleshooting this, so any tips on that would help me a great deal. It sounds very similar to this, but using SharpZLib results in the same thing.
Here's what I'm doing:
var inputFile = String.Format(#"{0}\{1}", inputDir, fileName);
var outputFile = String.Format(#"{0}\{1}.gz", inputDir, fileName);
var dcmpFile = String.Format(#"{0}\{1}", outputDir, fileName);
using (var input = File.OpenRead(inputFile))
using (var fileOutput = File.Open(outputFile, FileMode.Append))
using (GZipStream gzOutput = new GZipStream(fileOutput, CompressionMode.Compress, true))
{
input.CopyTo(gzOutput);
}
// Now, decompress
using (FileStream of = new FileStream(outputFile, FileMode.Open, FileAccess.Read))
using (GZipStream ogz = new GZipStream(of, CompressionMode.Decompress, false))
using (FileStream wf = new FileStream(dcmpFile, FileMode.Append, FileAccess.Write))
{
ogz.CopyTo(wf);
}
Your output file only contains a single line (gzipped) - but it contains all of the text data other than the line breaks.
You're repeatedly calling ReadLine() which returns a line of text without the line break and converting that text to bytes. So if you had an input file which had:
abc
def
ghi
You'd end up with an output file which was the compressed version of
abcdefghi
If you don't want that behaviour, why even go through a StreamReader in the first place? Just copy from the input FileStream straight to the GZipStream a block at a time, or use Stream.CopyTo if you're using .NET 4:
// Note how much simpler the code is using File.*
using (var input = File.OpenRead(inputFile))
using (var fileOutput = File.Open(outputFile, FileMode.Append))
using (GZipStream gzOutput = new GZipStream(os, CompressionMode.Compress, true))
{
input.CopyTo(gzOutput);
}
Also note that appending to a compressed file is rarely a good idea, unless you've got some sort of special handling for multiple "chunks" within a single file.

Categories

Resources