Java Swing+DOM API读取XML遇FileNotFoundException求助
问题:Java Swing程序读取XML文件时触发FileNotFoundException
我编写了一个基于Java Swing的用户界面程序,使用DOM API读取Catalogue.xml文件,实现通过下拉框选择导演查询对应影片的功能。但运行时触发java.io.FileNotFoundException,已尝试填写文件完整路径、将XML文件复制到build文件夹,均无法解决问题。以下是代码及报错堆栈信息:
程序代码
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import javax.swing.*; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.w3c.dom.Element; public class NewJFrame extends javax.swing.JFrame { private JComboBox<String> directorDropdown; private JButton searchButton; private JTextArea resultTextArea; public NewJFrame() { init(); } @SuppressWarnings("unchecked") private void init() { directorDropdown = new JComboBox<String>(); directorDropdown.setModel(new DefaultComboBoxModel<String>(new String[] {"Abdellah Ghayth", "Mouna Wacef", "ELaakad"})); getContentPane().add(directorDropdown); searchButton = new JButton("Search"); searchButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { // Get the selected director from the dropdown String nomRealisateur = directorDropdown.getSelectedItem().toString(); // Create a parser for the XML document DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); // Load the XML document into a Document object Document document = builder.parse(new File("Catalogue.xml")); // Find the films directed by the selected director and display their titles StringBuilder result = new StringBuilder(); NodeList films = document.getElementsByTagName("film"); for (int i = 0; i < films.getLength(); i++) { Element film = (Element) films.item(i); Element realisateur = (Element) film.getElementsByTagName("realisateur").item(0); if (realisateur.getAttribute("ref").equals(nomRealisateur)) { String titre = film.getAttribute("titre"); result.append(titre + "\n"); } } resultTextArea.setText(result.toString()); } catch (Exception ex) { ex.printStackTrace(); } } }); getContentPane().add(searchButton); resultTextArea = new JTextArea(); resultTextArea.setEditable(false); getContentPane().add(new JScrollPane(resultTextArea)); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); pack(); } public static void main(String args[]) { try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new NewJFrame().setVisible(true); try { // Spécifier le nom du réalisateur recherché String nomRealisateur = "ELaakad"; // Créer un parseur de document XML DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); // Charger le document XML dans un objet Document Document document = builder.parse(new File("Catalogue.xml")); // Obtenir une liste des éléments "film" dans le document NodeList films = document.getElementsByTagName("film"); // Créer un modèle de liste pour les titres de films DefaultListModel<String> listModel = new DefaultListModel<String>(); // Parcourir chaque élément "film" pour trouver ceux réalisés par le réalisateur spécifié for (int i = 0; i < films.getLength(); i++) { Element film = (Element) films.item(i); Element realisateur = (Element) film.getElementsByTagName("realisateur").item(0); // Vérifier si le réalisateur correspond à celui recherché if (realisateur.getAttribute("ref").equals(nomRealisateur)) { String titre = film.getAttribute("titre"); listModel.addElement(titre); } } // Créer une liste pour afficher les titres de films JList<String> list = new JList<String>(listModel); } catch (Exception e) { e.printStackTrace(); } } }); } }
报错堆栈
java.io.FileNotFoundException: "path" (The system cannot find the file specified) at java.base/java.io.FileInputStream.open0(Native Method) at java.base/java.io.FileInputStream.open(FileInputStream.java:216) at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157) at java.base/java.io.FileInputStream.<init>(FileInputStream.java:111) at java.base/sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:86) at java.base/sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:189) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:653) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:150) at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:861) at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:825) at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) at java.xml/com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:247) at java.xml/com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:342) at java.xml/javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:206) at NewJFrame$3.run(NewJFrame.java:132) at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86) at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:741) at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
排查方案
确认程序工作目录:Java程序默认从启动时的当前目录读取文件,不是build文件夹或类文件所在目录。在代码里加一行打印当前路径:
System.out.println(System.getProperty("user.dir"));把Catalogue.xml放到打印出的目录下即可。
改用类加载器读取资源:如果XML是项目资源,推荐用类加载器获取输入流,彻底避免路径问题。把读取XML的代码替换成:
InputStream is = getClass().getResourceAsStream("/Catalogue.xml"); if (is == null) { throw new FileNotFoundException("Catalogue.xml not found in classpath"); } Document document = builder.parse(is);注意要把XML放在项目的resources目录(Maven/Gradle项目),或者和编译后的类文件同目录,这样类加载器能找到它。
检查绝对路径写法:如果用绝对路径,Windows系统要转义反斜杠,比如
"C:\\Users\\你的用户名\\Catalogue.xml",或者直接用正斜杠"C:/Users/你的用户名/Catalogue.xml",避免路径字符串转义错误。移除冗余代码:main方法里有一段重复读取XML的逻辑,而且创建的JList也没添加到界面上,这段代码会重复触发文件查找错误,建议直接删掉。
内容的提问来源于stack exchange,提问作者Houssam Eddine
相关产品推荐
相关产品推荐

