介绍
我在网上找到了大量关于打开文件过多异常的信息,但我无法解决这个奇怪的情况。正如我所读到的,当超过操作系统中定义的进程打开的文件描述符的数量时,将引发异常。这些文件的性质是多种多样的。文件可以是套接字、文档等。而且我已经找到了打开在我的 Java 应用程序中实现的文件的可靠且安全的方法。
该应用程序是一个使用Boilerpipe算法下载网页的短程序。这样我就得到了那个网站最具代表性的内容。然后,我以适当的格式(TREC 格式)将其写入磁盘。这些网站的 URL 取自我使用JDBC 连接器访问的 MySQL 数据库。
所以,我认为可以从三个不同的地方抛出异常:
- 连接到数据库
- 与网站的 HTTP 连接
- 打开和写入文件
虽然,正如我所说,我认为我使用正确的方式打开和写入这些文件。
问题
有数千个 URL 需要处理,一段时间后抛出异常(这也使得调试变得非常困难......)。我不知道这是否重要,但 URL 分为不同的类别,我运行程序的不同实例以加快整个过程。类别不重叠,所以不应该有任何问题。
代码
为了使其更具可读性,我将仅展示简化的代码的这三个部分:
数据库访问
// Connect to database Connection dbconn = null; try { String dbUrl = "jdbc:mysql://" + dbServer + "/" + dbName; Class.forName ("com.mysql.jdbc.Driver").newInstance (); dbconn = DriverManager.getConnection(dbUrl, dbUser, dbPass); System.out.println ("Database connection established"); } catch (Exception e) { e.printStackTrace(); System.err.println ("Cannot connect to database server"); System.exit(-1); } System.out.println(" Downloading category: " + category); Statement s = null; try { s = dbconn.createStatement(); } catch (SQLException e) { System.err.println ("Error on creating the statement"); System.exit(-1); e.printStackTrace(); } String q = "SELECT resource,topic FROM " + "content_links " + "WHERE topic LIKE 'Top/" + category + "%';"; try { s.executeQuery(q); } catch(Exception e) { System.err.println ("Error on executing the SQL statement"); System.exit(-1); e.printStackTrace(); } ResultSet rs = null; try { rs = s.getResultSet (); } catch (SQLException e) { System.err.println ("Error on getting the result set"); System.exit(-1); e.printStackTrace(); } int count = 0, webError = 0; // work with the result set try { while (rs.next ()) { // MAIN LOOP } } catch (SQLException e) { System.err.println ("Error on getting next item"); System.exit(-1); e.printStackTrace(); } // Close connection to database if (dbconn != null) { try { dbconn.close (); System.out.println (" Database connection terminated"); } catch (Exception e) { /* ignore close errors */ } }
HTTP 连接,提取站点的标题和锅炉过滤器
try { String title = ""; org.jsoup.nodes.Document doc = Jsoup.connect(urlVal).get(); for (Element element : doc.select("*")) { if (element.tagName().equalsIgnoreCase("title")) { title = element.text(); } if (!element.hasText() && element.isBlock()) { element.remove(); } } String contents = ""; contents = NumWordsRulesExtractor.INSTANCE.getText(doc.text()); storeFile(id, urlVal, catVal, title, contents); } } catch (BoilerpipeProcessingException e) { System.err.println("Connection failed to: " + urlVal); } catch (MalformedURLException e1) { System.err.println("Malformed URL: " + urlVal); } catch(Exception e2) { System.err.println("Exception: " + e2.getMessage()); e2.getStackTrace(); }
写入文件
private static void storeFile(String id, String url, String cat, String title, String contents) { BufferedWriter out = null; try { out = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( new File(path + "/" + id + ".webtrec")),"UTF8")); // write in TREC format out.write("..."); } catch (IOException e) { System.err.println("Error: " + e.getMessage()); e.printStackTrace(); } finally { try { out.close(); } catch (IOException e) { System.err.println("Error: " + e.getMessage()); e.printStackTrace(); } }