472,951 Members | 1,575 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,951 software developers and data experts.

USB communications using StreamReader and StreamWriter

I'm doing some USB communications in C# and am running into a minor
annoyance. I'm using the Windows API CreateFile function to get a
SafeFileHandle, which I then stuff into a FileStream and from there
into StreamReader and StreamWriter objects. The StreamReader is
working beautifully, but the StreamWriter isn't. If I convert the
StreamWriter.BaseStream back to a FileStream and use its
SafeFileHandle in the Windows API WriteFile function to write the data
then everything works perfectly, but that defeats the purpose of
having the StreamWriter in the first place. I want to just use the
StreamWriter.Write() function. Is there something I'm doing
incorrectly? Here's some random excerpts from my code so you can sort
of see what I'm doing. The WnAPIWrapper is just my wrapper for
getting C# friendly objects from the Windows API:

// Get the input and output streams to the USB device from the Windows
API
// Basically just gets a SafeFileHandle to the USB device and puts it
into a FileStream
StreamReader fPipeIn = new
StreamReader(WinAPIWrapper.GetFileStreamFromGuid(D eviceGuid,
@"\PIPE00"));
StreamWriter fPipeOut = new
StreamWriter(WinAPIWrapper.GetFileStreamFromGuid(D eviceGuid,
@"\PIPE01"));

// At this point I can do fPipeIn.ReadLine() and it works very well

// Create the data to send to the device
int command = 11;
byte[] data = new byte[1]{(byte)command};

// This method does NOT work. Why? fPipeOut is set to AutoFlush by
the way
fPipeOut.Write(data);

// This method, accessing the Windows API WriteFile function directly
with the FileStream.SafeFileHandle, works just fine
WinAPIWrapper.WriteToStream((FileStream)fPipeOut.B aseStream, data);

Any help is much appreciated. I don't NEED to use the StreamWriter
since I have a method that works, but it would be cleaner and nicer if
I could.

Thanks!
Stu
Jul 15 '08 #1
3 5124
st*******@gmail.com wrote:
<snip>
// Create the data to send to the device
int command = 11;
byte[] data = new byte[1]{(byte)command};

// This method does NOT work. Why? fPipeOut is set to AutoFlush by
the way
fPipeOut.Write(data);
You're actually calling the StreamWriter.Write(object) overload, because
StreamWriter has no method for writing a byte[] (it's character-oriented,
not byte-oriented).

This ends up calling .ToString() on "data", which yields "System.Byte[]"...
This is one reason not to like overloads. (The moral here is actually not to
declare an overload that takes an "object" along with more specific
overloads. Unfortunately, it's too late now.)

You'll want to call it like this instead:

fPipeOut.Write((char) 11);

or use a char[], but not a byte[].

Beware that this method simply *does not work* for bytes 127, because
these will end up encoded in UTF-8. If you want to write arbitrary bytes,
you shouldn't use StreamWriter but instead operate directly on the Stream.
You can convert (portions of) byte arrays with the Encoder classes. The same
caveat applies to using StreamReader.

--
J.
Jul 15 '08 #2
Thanks, that worked perfectly. Now I'm having some issues with the
StreamReader. When I send a command to the device to stop streaming,
the StreamReader hangs. I've tried ReadLine, ReadToEnd,
DiscardBufferedData. They all hang when the device stops streaming.
Anything I'm doing wrong? I would think if there is nothing to read
then ReadLine would just return a blank string... I suppose the
device could be closing its outbound USB port thus severing the
connection, would that cause the StreamReader to hang? I was hoping
it might more gracefully wait for the stream to open again.
Jul 16 '08 #3
On Wed, 16 Jul 2008 09:53:29 -0700, <st*******@gmail.comwrote:
Thanks, that worked perfectly. Now I'm having some issues with the
StreamReader. When I send a command to the device to stop streaming,
the StreamReader hangs. I've tried ReadLine, ReadToEnd,
DiscardBufferedData. They all hang when the device stops streaming.
Anything I'm doing wrong?
That depends. But it sounds like your USB source doesn't provide an "end
of stream" indication when it's done. That's not actually all that
surprising to me. I don't know much about USB i/o, but assuming it's like
regular serial interfaces, it just doesn't have the idea of an "end of
stream".

DiscardBufferedData() is irrelevant (has nothing at all to do with the
question). ReadToEnd() won't return until the stream ends. Even
ReadLine() won't return until a full line has been received. If no more
data is sent, there's no way for a full line to be received. So either of
those read methods will simply block indefinitely.

Ideally, the _data_ in the stream would include some kind of termination
indication. If so, then you simply need to watch for that data, and close
the stream yourself when you see it.

Otherwise, you are probably going to have to make some assumptions about
the definition of "end of stream". Most likely in the form of a timeout.
You can use a timer, restarting it each time you successfully read some
data. Once the timer finally expires (i.e. you have not received any data
after the specified amount of time), you can then assume that the device
is done sending and close the stream at that point.

Again, I'm unfamiliar with USB i/o, but I suspect that if you've got one
thread blocked on a call to ReadLine() or similar, closing the stream will
cause that call to complete with an exception, allowing you to catch the
exception and correctly detect the pseudo-"end of stream" you've created.

Finally, I'd like to suggest that you seriously consider taking Jeroen's
advice to switch to using a regular Stream. My understanding is that your
stream is not just character input, but rather also includes binary data.
If this is the case, I think you will have more reliable, more
maintainable code by handling the character data yourself with a regular
Stream than by trying to shoe-horn binary data into the character-based
StreamWriter/StreamReader classes. (Though, the "end of stream" issue as
described above will be basically the same).

Pete
Jul 16 '08 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Gaia C via .NET 247 | last post by:
(Type your message here) Hi, I want to open a file to read from and then edit and write the text to another file. I am using StreamReader and StreamWriter for this purpose. The problem is that i...
9
by: ShadowOfTheBeast | last post by:
Hi, I have got a major headache understanding streamReader and streamWriter relationship. I know how to use the streamreader and streamwriter independently. but how do you write out using the...
1
by: R.L. | last post by:
See the code below, var 'content ' is suppose to be "Hello!", not "". Who knows why? Thanks ---------------------------------------- string text = "hello!"; MemoryStream stream = new...
13
by: mloichate | last post by:
I must read a very heavy-weight text plain file (usually .txt extension) )and replace a given character with another given character in all text inside the file. My application was working pretty...
1
by: Rob T | last post by:
Hi, I have a simple little program that I'm going to use to access our SMTP server. The below code works perfectly fine, but my question is if I were to try to execute the last line...
2
by: lprisr | last post by:
Hi, I have double byte characters in the content that I am returning using Web Services. However, the encoding in the xml file returned by Web Services is utf-8 and I am unable to read the...
3
by: curt.bathras | last post by:
I am trying to open and read a file using the following: BufferedStream stream = new BufferedStream(File.OpenRead(aFilename)); If the file specified by aFilename is being used by another...
5
by: Rob | last post by:
Hi, I have a VB.Net application that parses an HTML file. This file was an MS Word document that was saved as web page. My application removes all unnecessary code generated by MS Word and does...
6
by: Claire | last post by:
I've noticed after copying a text file line by line and comparing, that the original had several bytes of data at the beginning denoting its encoding. How do I use that in my copy? My original...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
0
by: Mushico | last post by:
How to calculate date of retirement from date of birth
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.