I am writting a mp3 player which streams songs from Internet. The problem is that I can't use Seek() method in ConnectStream.
I thinking maybe it's possible to copy ConnectStream to MemoryStream asynchronously during streaming and use MemoryStream's Seek() method.
Does anyone has idea is it possible? Or maybe someone knows other way how to do this?
Thanks.
If you are looking to allow the user to seek back and forth through the song, you are probably on the right track. Allocate a MemoryStream, and use the CopyTo method (assuming that you are on .NET 4), as follows:
var ms = new MemoryStream();
myConnectStream.CopyTo(ms);
If you want to download and seek at the same time (like a youtube video for instance), you need to use slightly more complex techniques. Rather than describe them in detail, I'll just refer you to the source:
http://msdn.microsoft.com/en-us/magazine/cc337900.aspx
Yes, this is possible with System.IO.MemoryStream. You are then buffering some of the stream in the local memory. Consider using System.IO.BufferedStream
Related
how to read from a stream - a BufferedStream without using heavy locks? I'm reading audio data from a file using NAudio. Since NAudio stream have lock on Read methods, I used BufferedStream as a wrapper. I need only read data. However, I lost thread-safety. How to make stream threadsafe without using locks?
Unfortunately I cannot read data in large blocks, because interface which I use contains method float GetSample(long) which read just 1 sample at once.
I've never used that library, but if I understand you correctly, your disk file is locking because you are reading it, so no other application can read it, is that correct?
In this case, it's not your app that's become multi-threaded, and you shouldn't need locks within your application. You do however have to make sure that the file is opened for read only puroposes allowing readonly access to other applications.
If NAudio offers the full set of parameters when opening a file, you'll be able to open the file with sharing allowed, otherwise if NAudio can be passed a stream to read from, you'll be able to open the file however you want and then pass the stream to NAudio.
https://msdn.microsoft.com/en-us/library/y973b725%28v=vs.110%29.aspx
I use _FileStream.Write(_ByteArray, 0, _ByteArray.Length); to write a bytearray to a file. I noticed that's very slow.
I read a line from a text file, convert it to a bytearray and then need to write it to a new (large > 500 Mb) file. Please some advice to speed up the write process.
FileStream.Write is basically what there is. It's possible that using a BufferedStream would help, but unlikely.
If you're really reading a single line of text which, when encoded, is 500MB then I wouldn't be surprised to find that most of the time is being spent performing encoding. You should be able to test that by doing the encoding and then throwing away the result.
Assuming the "encoding" you're performing is just Encoding.GetBytes(string), you might want to try using a StreamWriter to wrap the FileStream - it may work better by tricks like repeatedly encoding into the same array before writing to the file.
If you're actually reading a line at a time and appending that to the file, then:
Obviously it's best if you keep both the input stream and output stream open throughout the operation. Don't repeatedly read and then write.
You may get better performance using multiple threads or possibly asynchronous IO. This will partly depend on whether you're reading from and writing to the same drive.
Using a StreamWriter is probably still a good idea.
Additionally when creating the file, you may want to look at using a constructor which accepts a FileOptions. Experiment with the available options, but I suspect you'll want SequentialScan and possibly WriteThrough.
If your writing nothing but Byte arrays, have you tried using BinaryWriter's Write method? Writing in bulk would probably also help with the speed. Perhaps you can read each line, convert the string to its bytes, store those bytes for a future write operation (i.e in a List or something), and every so often (after reading x lines) write a chunk to the disk.
BinaryWriter: http://msdn.microsoft.com/en-us/library/ms143302.aspx
Background:
I'm trying to write a simple SoapExtension class to log inbound/outbound Soap messages from an asmx web service. Following this article on msdn, I have been able to get things working. However I'd really like to understand why/how it's working rather than just copy & pasting code.
The question:
What I'm stuggling to grasp specifically is the handling of the IO streams in the example. All other articles I've read on the web handle the streams in an identical way... first getting a reference to the original stream, creating an in memory "working" stream, and then swapping the contents as necessary.
First question is, what is meant by "stream chaining" in this context? My understaning of streams is that writing to any stream will automatically write to the 'inner' streams in a pipeline. If that's the case, why is it necessary to manually copy contents from one stream to another?
Second question is, in the examples Copy method they're creating a StreamReader and StreamWriter each time, without disposing them - is this not putting extra pressure on the GC? Doesn't seem like something you'd want on a high traffic web service... I tried wrapping both in using statements, but disposing the reader/writer also closed the stream which led to more serious errors. .NET 4 has new Stream.CopyTo(Stream) methods, but what would be a better approach for .NET 3.5?
Well, by chaining streams you can basically have different streams that do different things, in a chained sequence. For instance, you can have one stream that compresses the data, and then another stream that encrypts the data (or the opposite if we are moving in the other direction).
As for ChainStream itself, well... There are lots of things to say about this one. I really recommend this article called Inside of Chainstream, which is extremely in-depth and also covers most of the questions you have.
The chaining is done in the framework. You get the original stream and return the stream where you put your modified result. The framework will chain this new stream into any other extensions.
It is implemented this way because the chaining works "backwards". Normally you add new functionality on top of streams but in this case you want to deal with the information fed into the original stream.
Calling close on stream is the same as Dispose.
A decompression API that I am using has the following API:
Decode(Stream inStream,Stream outStream)
I'd like to create a wrapper around this API, such that I can create my own Stream class which offers up the decoded data.
Stream decodedStream=new BlaDecodeStream(inStream);
So that I can than use this stream as a parameter to the XmlReader constructor in the same way one might use the System.IO.Compression.GZipStream. As far as I can tell, the only other option is set outStream stream to a MemoryStream or to a FileStream and go in two hops. The files I am dealing with are enormous, so neither of these options are particularly attractive.
Before I go reinventing the wheel, is there any prior art that I might be able to draw from, or something in the BCL I might have missed? The CircularStream implementation here would go some of the way to helping, but I'm really looking for something similar that would block (as opposed to over/underrun) when the Stream's internal buffer is 'empty' when reading from it and block when the internal buffer is full when writing to it.
In this way it could serve as parameter outStream and simultaneously (i.e. from another thread) could be read from by the XmlReader.
I asked about a blocking stream reader a while ago. I implemented one of the suggestions and it works fine.
I need a C# implementation of Java's PushbackInputStream. I have made my own very basic one, but I wondered if there was a well tested and decently performing version already available somewhere. As it happens I always push back the same bytes I read so really it just needs to be able to reposition backwards, buffering up to a number of bytes I specify. (like Java's BufferedInputStream with the mark and reset methods).
Update: I should add that I can't simply reposition the stream as CanSeek may be false. (e.g. when the input steam is a NetworkStream)
The problem with pushing data back into a stream is that any readers that sit on top of the stream may already have a local buffer of data. This makes this approach very brittle. Personally, I would try to avoid this scenario, and use data constructs where I either don't need to push back, or can use single-byte Peek etc.
You need to build a wrapper class that either functions as a stream, but supports a buffer of the last X bytes so you can seek back at least for a limited distance, or something that isn't a stream at all where you can indeed "push data back into the input stream".
Either way you're going to have to write something yourself.
Can't you just use a System.IO.Stream and seek backwards after reading from current position?
stream.Seek(-1, System.IO.SeekOrigin.Current)
Where -1 could be a variable of how far you want to go back?
So long as the stream indicates it supports seeking (CanSeek) then
stream.Seek(-offset, System.IO.SeekOrigin.Current)
Will be fine.