JAVA: "AWT-EventQueue-0" java.lang.StackOverflowError 重复使用文件搜索抛出

JAVA: "AWT-EventQueue-0" java.lang.StackOverflowError Thrown on repeated use of file search

您好,感谢您花时间查看我的问题。

我正在构建一个递归搜索目录然后显示该目录中最大文件的名称的程序。第一次运行时,程序似乎运行良好,但如果我输入新路径并进行第二次搜索,程序将抛出 WhosebugError。

首先:我对该问题的研究告诉我,递归方面可能会创建一个无限循环,但对于我来说,我无法弄清楚它发生的位置或原因以及如何防止它从发生。

其次:如果这很重要,我正在使用一个包含各种其他文件夹和各种大小的文本文件的测试目录来测试该程序。我第一次 运行 该程序时,它显示了正确的文件名。

我 运行 遇到了完全的障碍。

这是我的堆栈跟踪:

Exception in thread "AWT-EventQueue-0" java.lang.WhosebugError
at sun.misc.Unsafe.allocateMemory(Native Method)
at sun.nio.fs.NativeBuffer.<init>(NativeBuffer.java:57)
at sun.nio.fs.NativeBuffers.allocNativeBuffer(NativeBuffers.java:49)
at sun.nio.fs.WindowsNativeDispatcher.asNativeBuffer(WindowsNativeDispatcher.java:1103)
at sun.nio.fs.WindowsNativeDispatcher.GetFileAttributesEx(WindowsNativeDispatcher.java:367)
at sun.nio.fs.WindowsFileAttributes.get(WindowsFileAttributes.java:309)
at sun.nio.fs.WindowsFileAttributeViews$Basic.readAttributes(WindowsFileAttributeViews.java:51)
at sun.nio.fs.WindowsFileAttributeViews$Basic.readAttributes(WindowsFileAttributeViews.java:38)
at sun.nio.fs.WindowsFileSystemProvider.readAttributes(WindowsFileSystemProvider.java:193)
at java.nio.file.Files.readAttributes(Files.java:1686)
at java.nio.file.Files.isRegularFile(Files.java:2172)
at bsimmons_cis257_a6.DirSearch.fileVisitor(DirSearch.java:31)
at bsimmons_cis257_a6.DirSearch.fileVisitor(DirSearch.java:37)
at bsimmons_cis257_a6.DirSearch.fileVisitor(DirSearch.java:37)
at bsimmons_cis257_a6.DirSearch.fileVisitor(DirSearch.java:37)
at bsimmons_cis257_a6.DirSearch.fileVisitor(DirSearch.java:37)
at bsimmons_cis257_a6.DirSearch.fileVisitor(DirSearch.java:37)
at bsimmons_cis257_a6.DirSearch.fileVisitor(DirSearch.java:37)
at bsimmons_cis257_a6.DirSearch.fileVisitor(DirSearch.java:37)
at bsimmons_cis257_a6.DirSearch.fileVisitor(DirSearch.java:37)

此后继续。

这是我的代码 -

主要Class:

package bsimmons_cis257_a6;

public class MainApp {

    public static void main(String[] args) {
        DirSearchGUI dirSearchGUI = new DirSearchGUI();
        dirSearchGUI.setLocationRelativeTo( null );
        dirSearchGUI.setVisible( true );
    }
}

图形用户界面:

package bsimmons_cis257_a6;

public class DirSearchGUI extends javax.swing.JFrame {



public DirSearchGUI() {


    initComponents();
    pathOutput.setEditable(false);

}

/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    jPanel1 = new javax.swing.JPanel();
    pathInput = new javax.swing.JTextField();
    pathInputLabel = new javax.swing.JLabel();
    jScrollPane1 = new javax.swing.JScrollPane();
    pathOutput = new javax.swing.JTextArea();
    buttonExit = new javax.swing.JButton();
    buttonSearch = new javax.swing.JButton();
    pathOutputLabel = new javax.swing.JLabel();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setTitle("Largest File Directory Search");

    pathInputLabel.setText("Enter a path:");

    pathOutput.setColumns(20);
    pathOutput.setRows(5);
    jScrollPane1.setViewportView(pathOutput);

    buttonExit.setText("Exit");
    buttonExit.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            buttonExitActionPerformed(evt);
        }
    });

    buttonSearch.setText("Search");
    buttonSearch.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            buttonSearchActionPerformed(evt);
        }
    });

    pathOutputLabel.setText("Search Results:");

    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jPanel1Layout.createSequentialGroup()
            .addGap(31, 31, 31)
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                .addComponent(buttonExit)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(pathInputLabel)
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                        .addGroup(jPanel1Layout.createSequentialGroup()
                            .addComponent(pathInput)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(buttonSearch))
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 560, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(pathOutputLabel)))
            .addContainerGap(22, Short.MAX_VALUE))
    );
    jPanel1Layout.setVerticalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jPanel1Layout.createSequentialGroup()
            .addGap(24, 24, 24)
            .addComponent(pathInputLabel)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(pathInput, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(buttonSearch, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addGap(11, 11, 11)
            .addComponent(pathOutputLabel)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 143, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(buttonExit)
            .addContainerGap())
    );

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addContainerGap())
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addContainerGap())
    );

    pack();
}// </editor-fold>                        

private void buttonExitActionPerformed(java.awt.event.ActionEvent evt) {                                           
       System.exit(0);
}                                          

private void buttonSearchActionPerformed(java.awt.event.ActionEvent evt) {                                             

    DirSearch dirSearch = new DirSearch();
    pathOutput.setText("");
    String output = dirSearch.fileSearch(pathInput.getText());
    pathOutput.append(output);
}                                            

/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    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(DirSearchGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(DirSearchGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(DirSearchGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(DirSearchGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new DirSearchGUI().setVisible(true);
        }
    });
}

// Variables declaration - do not modify                     
private javax.swing.JButton buttonExit;
private javax.swing.JButton buttonSearch;
private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTextField pathInput;
private javax.swing.JLabel pathInputLabel;
private javax.swing.JTextArea pathOutput;
private javax.swing.JLabel pathOutputLabel;
// End of variables declaration                   
}

我的第 3 个 Class 使用方法:

package bsimmons_cis257_a6;

import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class DirSearch {
    //attributes
    private Path path;
    private Path largestFile;

    //constructors

    //methods
    public String fileSearch(String pathString){
        path = Paths.get( pathString );
        if (Files.exists( path ) && Files.isDirectory( path )){
            fileVisitor();
        }
        return largestFile.toString();
    }

    public void fileVisitor(){
        try {
                DirectoryStream<Path> pathStream = 
                        Files.newDirectoryStream(path);
                for (Path p : pathStream ) {
                    long fileSize = 0;
                    if (Files.isRegularFile(p)){
                        if ( Files.size(p) > fileSize ){
                            fileSize = Files.size(p);
                            this.largestFile = p.getFileName();
                        }
                    } else {
                        fileVisitor();
                    }
                }
            } catch(IOException ex){}
    }



}

堆栈跟踪指向fileVisitor()方法中的循环,我看不到递归的终止条件。你打开路径(在调用之间不会改变),进入循环,当第一个 if 条件失败时你重新进入具有相同路径的方法,历史重复并最终以 WhosebugError。尝试更改 fileVisitor 方法以接受路径作为参数(然后您将不需要 Path path class 字段)并在 else 分支中删除路径的一部分你已经访问过。在方法的开头添加终止条件(例如,检查路径是否为空,如果是,则完成)。递归结束。