【发布时间】:2012-08-27 09:59:08
【问题描述】:
简介
我在网上找到了大量关于打开文件过多异常的信息,但我无法解决这个奇怪的情况。正如我所读到的,当超过操作系统中定义的进程打开的文件描述符的数量时,将引发异常。这些文件的性质是多种多样的。文件可以是套接字、文档等。我已经找到了打开在我的 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(); } }
【问题讨论】:
-
你应该发布你得到的异常的堆栈跟踪。
-
您多久调用一次“数据库访问”部分?什么时候关闭数据库连接?
-
@Flavio:我只执行该部分一次,因为 SQL 语句会查询给定类别的所有 URL。然后我循环遍历该
while statement中的结果集。数据库在执行结束时关闭,我将编辑问题并添加我错过的那部分代码。我会尝试获取该堆栈跟踪,但正如我所说,这需要我一段时间,可能需要几天!
标签: java file runtime-error