# IOS troubles with binary data on windows

**URL:** <https://www.ruby-forum.com/t/ios-troubles-with-binary-data-on-windows/119002>\
**Category:** Ruby\
**Created:** [November 2, 2007, 1:41am UTC](https://www.ruby-forum.com/t/ios-troubles-with-binary-data-on-windows/119002 "2007-11-02T01:41:59Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![metrix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/48db29/32.png) [@metrix](https://www.ruby-forum.com/u/metrix)\
**Post date:** [November 2, 2007, 1:41am UTC](https://www.ruby-forum.com/t/ios-troubles-with-binary-data-on-windows/119002/1 "2007-11-02T01:41:59Z")

</div>

I’m at a loss.

Writing data from a file to an IOS blows up on windows. You get ’  
Invalid argument (Errno::EINVAL)’.

The code is below. @ezstream is an IOS opened r+b. If I read the files  
with http it works. As in http\_req\_result.read\_body { |segment|  
@ezstream.write segment}…this works.

Any suggestions? It’s really strange.

Here is the code:

f = File.open(track\_info[‘file\_path’],‘rb’)  
chunk = ‘’

until chunk.nil?  
chunk = f.read(16000,‘rb’)  
unless chunk.nil?  
@ezstream.write chunk #blows up here  
end  
end

---

<div class="post-metadata">

**Author:** ![metrix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/48db29/32.png) [@metrix](https://www.ruby-forum.com/u/metrix)\
**Post date:** [November 2, 2007, 2:09am UTC](https://www.ruby-forum.com/t/ios-troubles-with-binary-data-on-windows/119002/2 "2007-11-02T02:09:32Z")

</div>

I just found an error in my code, but it wasn’t causing a problem

this:

chunk = f.read(16000,‘rb’)

should be:

chunk = f.read(16000)

I also jumped the gun a little. It doesn’t look like it’s a binary data  
problem. It looks like you can’t stream from a file to a IO.popen  
stream. I’m not sure if I’m right though.

The funny thing is I can @ezstream.write ‘any old string’ and it works.  
writing a chunk from a file, which always gets converted to a string,  
does not.

---

<div class="post-metadata">

**Author:** ![metrix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/48db29/32.png) [@metrix](https://www.ruby-forum.com/u/metrix)\
**Post date:** [November 2, 2007, 3:50am UTC](https://www.ruby-forum.com/t/ios-troubles-with-binary-data-on-windows/119002/3 "2007-11-02T03:50:15Z")

</div>

Ok…I confirmed this a few different ways. It may be a new bug.

On windows, you can’t send binary data from a file over to another  
system pipe. It blows up. It will work from a network socket to a system  
pipe, and it will work from a local text file to a system pipe, but not  
from a binary file to a system pipe.

---

<div class="post-metadata">

**Author:** ![metrix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/48db29/32.png) [@metrix](https://www.ruby-forum.com/u/metrix)\
**Post date:** [November 2, 2007, 4:18pm UTC](https://www.ruby-forum.com/t/ios-troubles-with-binary-data-on-windows/119002/4 "2007-11-02T16:18:51Z")

</div>

The chunk size isn’t the problem.

This code streams mp3 data to standard input for a pipe opened up an an  
executable called ezstream. Ezstream is a source for icecast server.

here is @ezstream:

@ezstream = IO.popen(“C:\Program  
Files\ezstream-0.4.3-win32\ezstream.exe -c “C:\Program  
Files\ezstream-0.4.3-win32\examples\stdin.xml””, “r+b”)

This code works on Windows:

url = get\_track\_url

Net::HTTP.start(url.host, url.port) do |http|  
http.request\_get(url.request\_uri, {“User-Agent”=\>“Mozilla/5.0  
(Windows; U; Windows NT 5.1; en-US; rv:1.8.1) Gecko/20061010  
Firefox/2.0”}) do |res|  
raise “Bad response :#{res.code}: #{res.body}” unless res.code ==  
“200”  
res.read\_body do |segment|  
@ezstream.write segment  
end  
end  
end

This code does not work on Windows:

f = File.open(get\_file\_path,‘rb’)  
count = nil  
until count == 0  
count = @ezstream.write(f.read(1024))  
#Invalid argument (Errno::EINVAL)

# you get a broken pipe exception with sysread and syswrite too

end

Any ideas what is so different about chunking a file from disk versus  
chunking the file from an http network stream?

---

<div class="post-metadata">

**Author:** ![metrix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/48db29/32.png) [@metrix](https://www.ruby-forum.com/u/metrix)\
**Post date:** [November 2, 2007, 12:54pm UTC](https://www.ruby-forum.com/t/ios-troubles-with-binary-data-on-windows/119002/5 "2007-11-02T12:54:54Z")

</div>

2007/11/2, Brandon C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Ok…I confirmed this a few different ways. It may be a new bug.
> 
> On windows, you can’t send binary data from a file over to another  
> system pipe. It blows up. It will work from a network socket to a system  
> pipe, and it will work from a local text file to a system pipe, but not  
> from a binary file to a system pipe.

Few remarks: if you post code then you should people give at least the  
chance to understand what’s going on. In your first posting it was  
not clear from the code shown what @ezstream is.

Note that there is no #read method which will accept a binary flag.  
Instead the portion read is put into the string provided. In your  
case this leads to unnecessary string creations that get overwritten  
immediately (‘rb’ will create a new string each time it is executed).

Then, did you consider decreasing the buffer size? 16,000 seems quite  
high. I’d start with 1,024.

Also, the looping can be done more elegantly:

while ( chunk = r.read(1024) )  
…  
end

If you want to be even more savvy you can do

chunk = “”  
while r.read(1024, chunk)  
…  
end

Cheers

robert

---

<div class="post-metadata">

**Author:** ![metrix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/48db29/32.png) [@metrix](https://www.ruby-forum.com/u/metrix)\
**Post date:** [November 2, 2007, 5:00pm UTC](https://www.ruby-forum.com/t/ios-troubles-with-binary-data-on-windows/119002/6 "2007-11-02T17:00:52Z")

</div>

It still fails with your your file copying code. Though last night I  
didn’t notice, it does write a little bit of data to the pipe , then  
ezstream closes. From ezstream’s output it looks like it can’t process  
the data sent from a file to the pipe, it blurts out socket error. It  
likes the data from an http stream though, and it’s likes the data when  
it’s not fed through standard input. You can give ezstream a list of  
tracks in it’s own config file too.

By the way, the same method works with .Net code. I was able to feed  
ezstream data to standard input with some .Net code and that works.

I’ve done a lot of work on Windows with Ruby and I’m getting tired of  
all the idiosyncrasies that pop up between linux and windows. I’m just  
going to switch to a linux work station. All my code gets deployed to  
linux anyway.

---

<div class="post-metadata">

**Author:** ![metrix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/48db29/32.png) [@metrix](https://www.ruby-forum.com/u/metrix)\
**Post date:** [November 2, 2007, 4:38pm UTC](https://www.ruby-forum.com/t/ios-troubles-with-binary-data-on-windows/119002/7 "2007-11-02T16:38:08Z")

</div>

2007/11/2, Brandon C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Files\ezstream-0.4.3-win32\examples\stdin.xml"", “r+b”)  
> “200”  
> count = nil  
> until count == 0  
> count = @ezstream.write(f.read(1024))  
> #Invalid argument (Errno::EINVAL)
> 
> # you get a broken pipe exception with sysread and syswrite too
> 
> end
> 
> Any ideas what is so different about chunking a file from disk versus  
> chunking the file from an http network stream?

Check the documentation, especially the return value of #write. Note  
also the copying algorithm I suggested. Hint: your file copying is  
flawed.

Cheers

robert
