• ベストアンサー

javaのプログラムが止まる

JAVAを使って、ホームページを読み込んでいるのですが、100000ページくらいのURLを読み込んだ辺りでよく止まってしまいます。なぜでしょうか? また、JAVAがURLを読み込んでいる時に、メールチェックをしたり、たくさんのホームページをIEで見ていても止まることが良くあります。 こういったエラー表示の出ないエラーを解決するにはどうしたらよいでしょうか?とても困っています。 教えていただけないでしょうか? 宜しくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.26

えーっと、諦めるのが早くないですか? それに、いろいろヒントや解説も書いてありますし、 どこがわからないのかが逆にわかりません。 それと、「時間がないので作って欲しい」という内容に読みとれますが、 丸投げやそれに類似のリクエストには、申し訳ありませんが応えられません。 これは、私の方針というか、気持ちの問題です。 前回、「こちらで追加してもいいのですが」と書いたため、こういう要望になったのだと 思いますが、言い回しの間違いです。 「こちらで追加できなくはないのですが」ということを言いたかったのでした。 すみません。 というわけですので、直接のコードは書きません。 その代り、質問等はわかる範囲でならいくらでもつきあいます。

mizuki_ff
質問者

お礼

長らく、回答いただき本当に、ありがとうございました。今、コードを勉強する時間がどうしても取れないため、また、時間が取れる時がありましたら新しく質問させていただきますので、その際は、ぜひ、お付き合いよろしくお願いいたします。

その他の回答 (25)

  • uzzra
  • ベストアンサー率43% (55/127)
回答No.5

Address already in use のエラーは、使用しようとしたアドレスが既に他のソケットで使われているときに発生するものです。 以下、試していないので、想像で書きます。 いくつか考えられる原因があります。 1) 同じアドレスを同時に(別スレッドで)開こうとしていないか。 URL.dat というファイルにURLを記述されているそうですが、 そこに重複したアドレスが存在しないでしょうか。 または、以下のような2つのアドレスは同時に処理できますか。 http://www.hoge.com/ http://www.hoge.com/~user/ 2) TIME_WAIT の問題 下記参考URLに詳しく書かれていますが、簡単に言えば、ソケットをcloseしても、すぐにソケットは閉じず、しばらくTIME_WAIT状態となって残るということです。つまり、1つのクライアントから大量の接続・切断を短時間のうちに繰り返すと問題が発生する可能性があるということです。 SO_REUSEADDRソケットオプションをTRUEにすることで対処できる可能性があります。 もしくは、一度開いたソケットを使い回すことで解決できます。

参考URL:
http://mikilab.doshisha.ac.jp/dia/research/report/2002/0408/005/report20020408005.html
mizuki_ff
質問者

補足

深夜の回答いただきありがとうございます。 回答いただいた後から、いろいろ、ソケットについて調べたのですが、私のレベルではよく分かりませんでした。 なんとなく、JAVAで使えそうなURLまではたどり着いたのですが・・・ もし、お時間がありましたら、これをどのように実装すればよいのか教えていただけないでしょうか? 宜しくお願い致します。 http://www.kt.rim.or.jp/~ksk/sock-faq/unix-socket-faq-ja-4.html

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.4

今気が付きましたけど、 #2で示したコードは、実際のものとは違うのですね? でしたら、このコードで同じ状況が発生するか試してください。

mizuki_ff
質問者

補足

回答いただきありがとうございます。 このファイル単体でも動作させてみたのですが、やはり発生しました。ただし、今回は実験的に、#2補足の if(loop == 2){の2を100にしてみました。 何百行かは正常に進むのですが、ある一定まで進むと、 address already in use: connect java というエラーがでます。 また、実際にやっては居ませんが、このエラーが出たということは、多分、何時間か作動させればそのうち止まるのではないかと考えています。 なにか、良い案はないでしょうか? 宜しくお願い致します。 1.ファイル「URL.dat」の内容 http://www.yomiuri.co.jp/ http://www.reuters.com/news.jhtml http://www.kyodo.co.jp/ http://ascii24.com/ http://www.china.org.cn/japanese/ という感じでドメインの異なる、URLを50000程度列挙しています。

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.3

なんか、プログラムの作りというか、流れがおかしい気がします。 一応、あなたの考えている、次のことを教えてもらえませんか? 1.ファイル「URL.dat」の内容 2.各クラス(Test、Kaiseki2)の役割 3.全体の流れ(概略で結構ですが、説明には各クラスを登場させてください)

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.2

すみません、ちょっとわかり難いのですが。 fr.write(i); } }       ←←←← in.close(); fr.close(); os.close(); break; 上の←に対応した括弧はどこですか?

mizuki_ff
質問者

お礼

お礼欄で申し訳ありませんが、追伸です。 class Kaiseki2 extends Thread {の fr.write(i+"\n"); という部分がありますが、実際のプログラムでは、ホームページ全部を記録するのではなく、ホームページ中の一部分だけを抜き出しています。 また、時々、 Unexcepted end of file from server address already in use: connect java というエラーも出ます。しかし、時間を置いてアクセスするとエラーを回避できるので、これが出たときにループにしています。 しかし、抜本的な解決になっていません。 もし、これについても、お分かりになりましたら、宜しくお願い致します。

mizuki_ff
質問者

補足

回答いただきありがとうございます。 しかも、単純ミスをしておりすみませんでした。 今度は、単体でも動くように改良しています。 import java.net.*; import java.io.*; class Test { public static void main(String args[]) throws IOException{ try { InputStream is = new FileInputStream("URL.dat"); BufferedReader br = new BufferedReader(new InputStreamReader(is)); int cnt = 1; int loop = 0; int cc = 0; int count = 0; for(;;) { loop++; cnt++; Kaiseki2 run[] = new Kaiseki2[cnt]; String h[] = new String[cnt]; h[cnt-1] = br.readLine(); if(h[cnt-1] != null) { run[cnt-1] = new Kaiseki2(h[cnt-1]); run[cnt-1].start(); }else{ break; } if(loop == 2){ count = cnt - 1; System.out.println("Kaiseki() : " + count); run[cnt-1].join(); loop=0; } } br.close(); is.close(); }catch(Exception ex){System.out.println("エラー: Kaiseki()");System.out.println(ex.getMessage());} } } class Kaiseki2 extends Thread { private String h = null; Kaiseki2(String str) { this.h = str; } public void run() { int LOOP_MAX = 10; int loopcnt = 0; int oldasincnt = 0; try { OutputStream os = new FileOutputStream("出力.txt",true); BufferedWriter fr = new BufferedWriter(new OutputStreamWriter(os)); URL url = new URL(h); while(loopcnt < LOOP_MAX){ try{ BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(),"JISAutoDetect")); for (;;) { String i = in.readLine(); if( i == null) {break;} fr.write(i+"\n"); } in.close(); fr.close(); os.close(); break; }catch(Exception e){ loopcnt ++; System.out.println(url); System.out.println(loopcnt); System.out.println("30秒休憩"); // ウェイト処理 System.out.println(e.getMessage()); Thread.sleep(30000); } } }catch(Exception ex){System.out.println("エラー: Kaiseki2()");System.out.println(ex.getMessage());} } }

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.1

>こういったエラー表示の出ないエラーを解決するにはどうしたらよいでしょうか? プログラムを作っていて、予定した動作と違っていたことはありませんか? 例えば、出力したファイルにレコードが10件あるはずなのに、1件しかなかったとか。 それと同じです。 処理がどのような流れで実行されるのかを想定しておいて、 その通りにいっているのかを確認しながら実行させます。 確認の方法は、処理の途中で変数を表示します。 そうやって、どこが悪いのかを特定します。 もしかしたら、特定の1行が悪いのではなく、処理の流れそのものに問題が あるのかもしれません。 頑張ってください。

mizuki_ff
質問者

補足

回答いただきありがとうございます。 それも何度か試してみたのですが、どうもわかりません。 WindowsOSの限界ですかね? 一応、参考までにコードを記載しておきます。 お分かりになる方、何か、お気づきの方、ご指摘、宜しくお願い致します。 public class Kaiseki { public void read() { try { InputStream is = new FileInputStream("URL.dat"); BufferedReader br = new BufferedReader(new InputStreamReader(is)); int cnt = 1; int loop = 0; int cc = 0; int count = 0; for(;;) { loop++; cnt++; Kaiseki2 run[] = new Kaiseki2[cnt]; String h[] = new String[cnt]; h[cnt-1] = br.readLine(); if(h[cnt-1] != null) { run[cnt-1] = new Kaiseki2(h[cnt-1]); run[cnt-1].start(); }else{ break; } if(loop == 8){ count = cnt - 1; System.out.println("Kaiseki() : " + count); run[cnt-1].join(); loop=0; } } br.close(); is.close(); }catch(Exception ex){System.out.println("エラー: Kaiseki()");System.out.println(ex.getMessage());} } } class Kaiseki2 extends Thread { private String h = null; Kaiseki2(String str) { this.h = str; } public void run() { int LOOP_MAX = 10; int loopcnt = 0; int oldasincnt = 0; try { OutputStream os = new FileOutputStream("出力.txt",true); BufferedWriter fr = new BufferedWriter(new OutputStreamWriter(os)); URL url = new URL(h); while(loopcnt < LOOP_MAX){ try{ BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(),"JISAutoDetect")); for (;;) { String i = in.readLine(); if( i == null) {break;} fr.write(i); } } in.close(); fr.close(); os.close(); break; }catch(Exception e){ loopcnt ++; System.out.println(url); System.out.println(loopcnt); System.out.println("30秒休憩"); // ウェイト処理 System.out.println(e.getMessage()); Thread.sleep(30000); } } } catch(Exception ex) { System.out.print("エラーkaiseki2");System.out.println(ex.getMessage()); } } }

関連するQ&A