I have a Neurotec NTemplate with one Finger record. Now i want to Serialize it with c# - protobuf-net. I dont getting any exeption but my MemoryStream is emplty.
what might be the problem?
code Is below:(where tenPrintTemplate is a NTemplate)
tenPrintTemplate.AddFingers(fingerPrintTemplate.Save());
//start Proto Buffer serialization
MemoryStream stream = new MemoryStream();
RuntimeTypeModel.Default.InferTagFromNameDefault = true;
RuntimeTypeModel.Default.Add(typeof(NTemplate), false);
ProtoBuf.Serializer.Serialize<NTemplate>(stream, tenPrintTemplate);
Here you've told it not to apply any standard pattern / configuration logic:
RuntimeTypeModel.Default.Add(typeof(NTemplate), false);
so you have basically told it "serialize nothing". If you specify false, it expects you to tell it how you want it to work, for example by using Add on the MetaType that is returned. I suspect you could also just specify true if it has suitable attributes.
Note that 0 is a perfectly reasonable length for protobuf-net and an object that doesn't have anything interesting to mention on the wire.
I have got the solution of serializing Neurotec's NTemplate using C# Protobuf-net. i'm adding the solution code below. if anyone face the same problem please use it as your solution.
//Its a NTemplate of TenPrint
tenPrintTemplate.AddFingers(fingerPrintTemplate.Save());
//start Proto Buffer serialization
MemoryStream stream = new MemoryStream();
int tenpritnTemplateSize = tenPrintTemplate.GetSize();
NBuffer buffer = new NBuffer(tenpritnTemplateSize);
// saving fingers template to buffer.
tenPrintTemplate.Save(buffer);
ProtoBuf.Serializer.Serialize<byte[]>(stream, buffer.ToArray());
Related
It's me again and I have another problem. Somewhere, I've found following code:
private T DeepDeserialize<T>(string fileName)
{
T returnValue;
using (FileStream str = new FileStream(fileName, FileMode.Open))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
returnValue = (T)binaryFormatter.Deserialize(str);
}
return returnValue;
}
I've modified some classes today and now, it always throws an error, which could be translated like this: Before completing the analysis was detected ending stream (I don't know the right translation, the error message is in my language, not in English)
I've tried to insert str.Position = 0; between these two lines in using, which I've found somewhere here, but it doesn't help.
Can someone help me to make it work again? I have no ideas what to do...
You have changed the binary layout of your files but most likely trying to deserialize old files. This is not gonna work. You have to serialize new versions first.
P.S. If you would consider versioning and custom formatter at early stages, you might be able to deserialize old data with new classes, depending on how drastic was your change
I have been using a Xml serializer to serialize an class and saved it into an object which i later will send to a server. Due the amount of messages i send to the server i decided to change the serialization method into something that will result into something smaller in size.
I found protobuf-net but i only did find documentation about how to serialize a class into a file stream. It seems to me that saving to a file then send it to the server would not be very effective if you send over 100 packages every second.
So my question is , how can i serialize a class and save it into an object?
protobuf-net can write to (or read from) any Stream implementation. FileStream is just an example. In the case of communications between machines, this could be a NetworkStream. If you just want to get an in-memory form, then use MemoryStream. For example:
byte[] chunk;
using(var ms = new MemoryStream())
{
Serializer.Serialize(ms, obj);
chunk = ms.ToArray();
}
// now do something interesting with 'chunk'
I'm trying to reimplement an existing Matlab 8-band equalizer GUI I created for a project last week in C#. In Matlab, songs load as a dynamic array into memory, where they can be freely manipulated and playing is as easy as sound(array).
I found the NAudio library which conveniently already has Mp3 extractors, players, and both convolution and FFT defined. I was able to open the Mp3 and read all its data into an array (though I'm not positive I'm going about it correctly.) However, even after looking through a couple of examples, I'm struggling to figure out how to take the array and write it back into a stream in such a way as to play it properly (I don't need to write to file).
Following the examples I found, I read my mp3's like this:
private byte[] CreateInputStream(string fileName)
{
byte[] stream;
if (fileName.EndsWith(".mp3"))
{
WaveStream mp3Reader = new Mp3FileReader(fileName);
songFormat = mp3Reader.WaveFormat; // songFormat is a class field
long sizeOfStream = mp3Reader.Length;
stream = new byte[sizeOfStream];
mp3Reader.Read(stream, 0, (int) sizeOfStream);
}
else
{
throw new InvalidOperationException("Unsupported Exception");
}
return stream;
}
Now I have an array of bytes presumably containing raw audio data, which I intend to eventually covert to floats so as to run through the DSP module. Right now, however, I'm simply trying to see if I can play the array of bytes.
Stream outstream = new MemoryStream(stream);
WaveFileWriter wfr = new WaveFileWriter(outstream, songFormat);
// outputStream is an array of bytes and a class variable
wfr.Write(outputStream, 0, (int)outputStream.Length);
WaveFileReader wr = new WaveFileReader(outstream);
volumeStream = new WaveChannel32(wr);
waveOutDevice.Init(volumeStream);
waveOutDevice.Play();
Right now I'm getting errors thrown in WaveFileReader(outstream) which say that it can't read past the end of the stream. I suspect that's not the only thing I'm not doing correctly. Any insights?
Your code isn't working because you never close the WaveFileWriter so its headers aren't written correctly, and you also would need to rewind the MemoryStream.
However, there is no need for writing a WAV file if you want to play back an array of byes. Just use a RawSourceWaveStream and pass in your MemoryStream.
You may also find the AudioFileReader class more suitable to your needs as it will provide the samples as floating point directly, and allow you to modify the volume.
I need to generate a huge xml file from different sources (functions). I decide to use XmlTextWriter since it uses less memory than XmlDocument.
First, initiate an XmlWriter with underlying MemoryStream
MemoryStream ms = new MemoryStream();
XmlTextWriter xmlWriter = new XmlTextWriter(ms, new UTF8Encoding(false, false));
xmlWriter.Formatting = Formatting.Indented;
Then I pass the XmlWriter (note xml writer is kept open until the very end) to a function to generate the beginning of the XML file:
xmlWriter.WriteStartDocument();
xmlWriter.WriteStartElement();
// xmlWriter.WriteEndElement(); // Do not write the end of root element in first function, to add more xml elements in following functions
xmlWriter.WriteEndDocument();
xmlWriter.Flush();
But I found that underlying memory stream is empty (by converting byte array to string and output string). Any ideas why?
Also, I have a general question about how to generate a huge xml file from different sources (functions). What I do now is keeping the XmlWriter open (I assume the underlying memory stream should open as well) to each function and write. In the first function, I do not write the end of root element. After the last function, I manually add the end of root element by:
string endRoot = "</Root>";
byte[] byteEndRoot = Encoding.ASCII.GetBytes(endRoot);
ms.Write(byteEndRoot, 0, byteEndRoot.Length);
Not sure if this works or not.
Thanks a lot!
Technically you should only ask one question per question, so I'm only going to answer the first one because this is just a quick visit to SO for me at the moment.
You need to call Flush before attempting to read from the Stream I think.
Edit
Just bubbling up my second hunch from the comments below to justify the accepted answer here.
In addition to the call to Flush, if reading from the Stream is done using the Read method and its brethren, then the position in the stream must first be reset back to the start. Otherwise no bytes will be read.
ms.Position = 0; /*reset Position to start*/
StreamReader reader = new StreamReader(ms);
string text = reader.ReadToEnd();
Console.WriteLine(text);
Perhaps you need to call Flush() on the xml stream before checking the memory streazm.
Make sure you call Flush on the XmlTextWriter before checking the memory stream.
I'm trying to implement file compression to an application. The application has been around for a while, so it needs to be able to read uncompressed documents written by previous versions. I expected that DeflateStream would be able to process an uncompressed file, but for GZipStream I get the "The magic number in GZip header is not correct" error. For DeflateStream I get "Found invalid data while decoding". I guess it does not find the header that marks the file as the type it is.
If it's not possible to simply process an uncompressed file, then 2nd best would be to have a way to determine whether a file is compressed, and choose the method of reading the file. I've found this link: http://blog.somecreativity.com/2008/04/08/how-to-check-if-a-file-is-compressed-in-c/, but this is very implementation specific, and doesn't feel like the right approach. It can also provide false positives (I'm sure this would be rare, but it does indicate that it's not the right approach).
A 3rd option I've considered is to attempt using DeflateStream, and fallback to normal stream IO if an exception occurs. This also feels messy, and causes VS to break at the exception (unless I untick that exception, which I don't really want to have to do).
Of course, I may simply be going about it the wrong way. This is the code I've tried in .Net 3.5:
Stream reader = new FileStream(fileName, FileMode.Open, readOnly ? FileAccess.Read : FileAccess.ReadWrite, readOnly ? FileShare.ReadWrite : FileShare.Read);
using (DeflateStream decompressedStream = new DeflateStream(reader, CompressionMode.Decompress))
{
workspace = (Workspace)new XmlSerializer(typeof(Workspace)).Deserialize(decompressedStream);
if (readOnly)
{
reader.Close();
workspace.FilePath = fileName;
}
else
workspace.SetOpen(reader, fileName);
}
Any ideas?
Thanks!
Luke.
Doesn't your file format have a header? If not, now is the time to add one (you're changing the file format by supporting compression, anyway). Pick a good magic value, make sure the header is extensible (add a version field, or use specific magic values for specific versions), and you're ready to go.
Upon loading, check for the magic value. If not present, use your current legacy loading routines. If present, the header will tell you whether the contents are compressed or not.
Update
Compressing the stream means the file is no longer an XML document, and thus there's not much reason to expect the file can't contain more than your data stream. You really do want a header identifying your file :)
The below is example (pseudo)-code; I don't know if .net has a "substream", SubRangeStream is likely something you'll have to code yourself (DeflateStream probably adds it's own header, so a substream might not be necessary; could turn out useful further down the road, though).
Int64 oldPosition = reader.Position;
reader.Read(magic, 0, magic.length);
if(IsRightMagicValue(magic))
{
Header header = ReadHeader(reader);
Stream furtherReader = new SubRangeStream(reader, reader.Position, header.ContentLength);
if(header.IsCompressed)
{
furtherReader = new DeflateStream(furtherReader, CompressionMode.Decompress);
}
XmlSerializer xml = new XmlSerializer(typeof(Workspace));
workspace = (Workspace) xml.Deserialize(furtherReader);
} else
{
reader.Position = oldPosition;
LegacyLoad(reader);
}
In real-life, I would do things a bit differently - some proper error handling and cleanup, for instance. Also, I wouldn't have the new loader code directly in the IsRightMagicValue block, but rather I'd spin off the work either based on the magic value (one magic value per file version), or I would keep a "common header" portion with fields common to all versions. For both, I'd use a Factory Method to return an IWorkspaceReader depending on the file version.
Can't you just create a wrapper class/function for reading the file and catch the exception? Something like
try
{
// Try return decompressed stream
}
catch(InvalidDataException e)
{
// Assume it is already decompressed and return it as it is
}