トップ «前の日記(2015-10-16) 最新 次の日記(2015-10-24)» 編集

日々の破片

著作一覧

2015-10-21

_ JavaのURLConnectionとC#のWebRequest/WebResponseの違い

C#でHTTPクライアントを久々に書いて数分間何が起きたか混乱したのでメモ。

原因は、Streamの仕様の差にある。

Javaで簡単にHTTPクライアントを作るにはURLConnectionを使う。

URLConnection c = new URL("http://....").openConnection();
...
try (InputStream is = c.getInputStream()) {
    byte[] buff = new byte[16384];
    int len;
    while (len = is.read(read(buff)) >= 0) {
        if (len == 0) continue;
        ...
    }
} catch (Exception e) {
    throw new IllegalStateException("Why ?", e);
}

というように、長さ0の読み込みを正常処理に織り込む必要がある。

If the length of b is zero, then no bytes are read and 0 is returned; otherwise, there is an attempt to read at least one byte. If no byte is available because the stream is at the end of the file, the value -1 is returned; otherwise, at least one byte is read and stored into b. -InputStream#read(byte[])

この仕様が念頭にあったので、つい次のように書いて無限ループにはまった。

var req = WebRequest.Create("http://....");
...
using (var resp = req.GetResponse()) 
using (var is = resp.GetResponseStream())
{
    var buff = new byte[16384];
    int len;
    while ((len = is.Read(buff, 0, buff.Length)) >= 0) 
    {
        if (len == 0) continue;
        ...
    }
    is.Close();
}

.NET FrameworkのStream.Readは、

The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero (0) if the end of the stream has been reached. -Stream.Read

というわけで、EOFは0を返す。

    while ((len = is.Read(buff, 0, buff.Length)) > 0) 
    {
        ...
    }

と修正して完了。

こんなところに非同期IOに対する考え方の違いが影響していておもしろい。


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|06|07|08|09|10|11|12|

ジェズイットを見習え