2011-05-03 64 views
10

目前我正在研究一個可以用來讀取由url指定的網站內容的類。我只是用java.iojava.net開始我的冒險,所以我需要諮詢我的設計。將網站內容讀入字符串

用法:

TextURL url = new TextURL(urlString); 
String contents = url.read(); 

我的代碼:

package pl.maciejziarko.util; 

import java.io.*; 
import java.net.*; 

public final class TextURL 
{ 
    private static final int BUFFER_SIZE = 1024 * 10; 
    private static final int ZERO = 0; 
    private final byte[] dataBuffer = new byte[BUFFER_SIZE]; 
    private final URL urlObject; 

    public TextURL(String urlString) throws MalformedURLException 
    { 
     this.urlObject = new URL(urlString); 
    } 

    public String read() 
    { 
     final StringBuilder sb = new StringBuilder(); 

     try 
     { 
      final BufferedInputStream in = 
        new BufferedInputStream(urlObject.openStream()); 

      int bytesRead = ZERO; 

      while ((bytesRead = in.read(dataBuffer, ZERO, BUFFER_SIZE)) >= ZERO) 
      { 
       sb.append(new String(dataBuffer, ZERO, bytesRead)); 
      } 
     } 
     catch (UnknownHostException e) 
     { 
      return null; 
     } 
     catch (IOException e) 
     { 
      return null; 
     } 

     return sb.toString(); 
    } 

    //Usage: 
    public static void main(String[] args) 
    { 
     try 
     { 
      TextURL url = new TextURL("http://www.flickr.com/explore/interesting/7days/"); 
      String contents = url.read(); 

      if (contents != null) 
       System.out.println(contents); 
      else 
       System.out.println("ERROR!"); 
     } 
     catch (MalformedURLException e) 
     { 
      System.out.println("Check you the url!"); 
     } 
    } 
} 

我的問題是: 是否達到我想要有什麼好辦法?有沒有更好的解決方案?

我特別不喜歡sb.append(new String(dataBuffer, ZERO, bytesRead));,但我無法用其他方式表達。每次迭代創建一個新的字符串是否好?我想不。

還有其他弱點嗎?

在此先感謝!

回答

15

請考慮使用URLConnection來代替。此外,您可能還想利用Apache Commons IO中的IOUtils使字符串讀取更容易。例如:

URL url = new URL("http://www.example.com/"); 
URLConnection con = url.openConnection(); 
InputStream in = con.getInputStream(); 
String encoding = con.getContentEncoding(); // ** WRONG: should use "con.getContentType()" instead but it returns something like "text/html; charset=UTF-8" so this value must be parsed to extract the actual encoding 
encoding = encoding == null ? "UTF-8" : encoding; 
String body = IOUtils.toString(in, encoding); 
System.out.println(body); 

如果你不想使用IOUtils我可能會改寫上述類似的東西線:

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
byte[] buf = new byte[8192]; 
int len = 0; 
while ((len = in.read(buf)) != -1) { 
    baos.write(buf, 0, len); 
} 
String body = new String(baos.toByteArray(), encoding); 
+0

謝謝。我喜歡URLConnection!我想我應該在我的項目中使用它。 – 2011-05-03 10:41:21

+0

我接受了你的回答。有用! – 2011-05-03 10:53:26

+0

請注意,應該使用con.getContentType()而不是'con.getContentEncoding()',但它返回類似於「」text/html; charset = UTF-8「'的名稱,所以必須按順序解析該值以提取實際的編碼(我已經添加了對上面的代碼的評論,以反映這一點) – xav 2016-08-16 19:48:15

2

除非這是某種你想爲學習而編碼的練習......我不會重新發明輪子,我會使用HttpURLConnection

HttpURLConnection提供了良好的封裝機制來處理HTTP協議。例如,你的代碼不適用於HTTP重定向,HttpURLConnection會爲你解決這個問題。

+0

謝謝!我不知道'HttpURLConnection'。我需要檢查它。這也是一些練習:-) – 2011-05-03 10:15:45

2

你可以用你的InputStreamReaderInputStream,並且可以使用it's read() method來直接讀取字符數據(請注意,應該在創建Reader時指定了編碼,但找出任意URL的編碼並不重要)。然後,只需撥打sb.append(),您剛剛閱讀的char[](以及正確的偏移量和長度)。

5

我強烈建議使用專用的圖書館,像HtmlParser

Parser parser = new Parser (url); 
NodeList list = parser.parse (null); 
System.out.println (list.toHtml()); 

編寫自己的HTML解析器是這樣一個寬鬆的時間。這裏是its maven dependency。挖掘其功能,請看its JavaDoc

望着下面的示例應該是令人信服的:

Parser parser = new Parser(url); 
NodeList movies = parser.extractAllNodesThatMatch(
    new AndFilter(new TagNameFilter("div"), 
    new HasAttributeFilter("class", "movie"))); 
0

嘿請使用代碼的這些線,這將幫助ü..

<!DOCTYPE html> 
    <html> 
     <head> 
      <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> 
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
      <title>JSP Page</title> 

     </head> 
     <body> 
      <h1>Hello World!</h1> 






     URL uri= new URL("Your url"); 
     URLConnection ec = uri.openConnection(); 
     BufferedReader in = new BufferedReader(new InputStreamReader(
       ec.getInputStream(), "UTF-8")); 
     String inputLine; 
     StringBuilder a = new StringBuilder(); 
     while ((inputLine = in.readLine()) != null) 
      a.append(inputLine); 
     in.close(); 

     out.println(a.toString()); 
0

我知道這是一個老問題,但我相信其他人也會找到它。

如果你不介意額外的依賴關係,這裏有一個非常簡單的方法

Jsoup.connect("http://example.com/").get().toString() 

你需要一個Jsoup庫,但你可以快速使用Maven/gradle這個添加它,它也允許操縱頁面的內容並找到特定的節點。