##経緯
- JRubyの#openがWindows10環境だとエラーを吐く
- Java側で実装してみよう
- jisautodetect使うとutf-8の場合ダメだ
- 下のコードに至る
※特定のURLだけなので普通はこんな必要ないと思います
##入出力
- 引数
- url(変数名 : link)
- タイムアウトする時間(変数名 : time_limit)
- 戻り値
- 成功時 : 正しい(?)ファイル文字列
- 失敗時 : 空文字列
##コード
JavaOpen.java
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class JavaOpen{
public static String open(String link, int time_limit){
String html = "";
try {
URL url = new URL(link);
URLConnection con = url.openConnection();
con.setConnectTimeout(time_limit*300);
con.setReadTimeout(time_limit*700);
try (InputStream is = con.getInputStream();){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] byteChunk = new byte[8192];
int n;
while ( (n = is.read(byteChunk)) > 0 ) {
baos.write(byteChunk, 0, n);
}
byte[] bytes = baos.toByteArray();
html = bytesToHtml(bytes);
} catch (IOException e) {
e.printStackTrace ();
}
} finally {
return html;
}
}
public static String bytesToHtml(byte[] src) throws UnsupportedEncodingException {
String[] char_codes = { "UTF8","SJIS","EUC_JP","EUC_JP_LINUX","EUC_JP_Solaris" };
for (String cc: char_codes){
String s_tmp = new String(src, cc);
byte[] b_tmp = s_tmp.getBytes(cc);
if (Arrays.equals(src, b_tmp)) {
return s_tmp;
}
}
return "";
}
}
##コメント
-
String[] char_codes = { "UTF8","SJIS","EUC_JP","EUC_JP_LINUX","EUC_JP_Solaris" };
は自分のアクセスしうる可能性がある文字コードなのでご自由にどうぞ - 変数名time_limitの代案が思いつきたかったです...
-
setConnectTimeout
:setReadTimeout
=3 : 7で配分したけど、、普通はどうなんでしょうか? - 8192byteずつではなく一度に読み込む方法を知りたかったけど、動けばいいやの意思に負けた
##参考