【问题标题】:JAVA: "AWT-EventQueue-0" java.lang.StackOverflowError Thrown on repeated use of file searchJAVA:“AWT-EventQueue-0” java.lang.StackOverflowError 在重复使用文件搜索时抛出
【发布时间】:2016-05-06 14:46:01
【问题描述】:

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

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

首先:我对该问题的研究告诉我,递归方面可能会创建一个无限循环,但对于我的一生,我无法弄清楚它发生在哪里或为什么会发生以及如何防止它发生.

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

我遇到了一个完全的障碍。

这是我的堆栈跟踪:

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
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)

然后继续。

这是我的代码 -

主类:

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                   
}

还有我的第三堂课:

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){}
    }



}

【问题讨论】:

    标签: java recursion stack-overflow


    【解决方案1】:

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

    【讨论】:

    • 这很棒。经过一番摆弄,这完美地工作了。我最终需要做的就是改变它,以便 fileVisitor() 方法现在接受一个 Path 参数。在 fileSearch() 方法中,它采用“path”路径,在 fileVisitor() 方法的递归段中,它采用“p”路径。据我所知,它似乎工作得很好。我从来没有机会尝试删除以前访问过的路径,但是我尝试在一次代码执行中搜索多个路径并且不再出现任何异常。非常感谢你的帮助。我快疯了。你是一个救生员。
    猜你喜欢
    • 2017-05-09
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-10
    • 2015-01-12
    • 1970-01-01
    • 2013-10-12
    相关资源
    最近更新 更多