2012-03-06 33 views
-1

我嘗試使用下面的代碼來讀取網頁:爲什麼在嘗試將Reader重置爲0位置時出現異常錯誤?

URL url = new URL("somewebsitecomeshere"); 
       URLConnection c = url.openConnection(); 
       if(getHttpResponseCode(c) == 200) 
       { 

        if (isContentValid(c))//accept html/xml only! 
        { 
         InputStream is = c.getInputStream(); 


         Reader r = new InputStreamReader(is); 


         System.out.println(r.toString()); 
               //after commenting this everything works great! 
         setHTMLString(getStringFromReader(r)); 
         System.out.println(getHTMLString()); 

         ParserDelegator parser = new ParserDelegator(); 
         parser.parse(r, new Parser(url), true); 
         r.close(); 
         is.close(); 

         try { 
          Thread.sleep(500); 
         } catch (InterruptedException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 
        } 
        else 
         log("content is not valid!"); 
       } 
       else 
       { 
        System.out.println("ERROR" + c.getContentType() + c.getURL()); 
       } 
//--------------------------------------------------- 
    private String getStringFromReader(Reader reader) throws IOException { 
      char[] arr = new char[8*1024]; // 8K at a time 
      StringBuffer buf = new StringBuffer(); 
      int numChars; 

      while ((numChars = reader.read(arr, 0, arr.length)) > 0) { 
       buf.append(arr, 0, numChars); 
      } 
       //Reset position to 0 
      reader.reset(); 

      return buf.toString(); 
      } 

如果嘗試讀取使用getStringFromReader()字符串代碼的其餘部分將由於改變讀者的位置EOF所以我試圖忽視位置重置爲0,但我得到了以下錯誤:

java.io.IOException: reset() not supported 
    at java.io.Reader.reset(Unknown Source) 
    at sample.getStringFromReader(Spider.java:248) 
    at default(sample.java:286) 
    at default.main(sample.java:130) 

我怎樣才能讀者位置重置爲0?

回答

1

簡而言之,您的信息流不支持重置或標記方法。檢查結果如下:

is.markSupported() 

長答案,InputStream是字節流。字節可以來自文件,網絡資源,字符串等。所以基本上,有些流不支持將讀取器位置重置爲流的開始位置,而其他流則是(隨機訪問文件)。

來自網站的流通常會使用底層網絡連接來提供數據。這意味着它支持底層網絡協議(例如TCP/IP)來支持或不重置流,通常它們不會。

爲了重置任何流,你必須知道整個流程,從開始到結束。網絡通信發送一堆包(可能按順序或不按順序)傳輸數據。軟件包可能會丟失或甚至被複制,因此正常情況下信息會在收到時進行緩衝和解釋。在網絡層面重建所有消息將是非常昂貴的。所以這通常取決於接收器,如果它想這樣做的話。

你的情況如果你想要的是打印輸入流,我建議創建一個自定義的InputStream,它接收原始的InputStream,並且只要它被讀取,它就會打印讀取值並同時返回它。例如:

class MyInputStream extends InputStream { 

    InputStream original = null; 

    public MyInputStream(InputStream original) { 
    this.original = original; 
    } 

    @Override 
    public int read() throws IOException { 
    int c = original.read(); 
    System.out.printf("%c", c); 
    return c; 
    } 
} 

然後用包裝你原來的InputStream:

. 
. 
. 

InputStream myIs = new MyInputStream(is); 
Reader r = new InputStreamReader(myIs); 

. 
. 
. 

希望它能幫助。

1

InputStreamReader不支持reset()。另外,您之前沒有調用mark(0)。 你可以做的是將你的閱讀器包裝在足夠大小的BufferedReader中,以便支持重置。如果你不能這樣做,那麼你應該嘗試打開一個到你的URL的新連接。

相關問題