java.io.FileNotFoundException和(设备上没有剩余空间)

3
我有一份Java代码,它应该读取一个0.5M的文件并在删除一些无用信息后进行写入(我正在使用Enron电子邮件数据集)。
public void getInboxFiles(File directory){
    File[] usersFolders;
    File[] userFolders;
    File[] inboxFiles;
    usersFolders = directory.listFiles();
    for(File temp:usersFolders){
        userFolders = temp.listFiles();         
        for(File temp2:userFolders){                                    
            inboxFiles = temp2.listFiles();
            for(File tmp3:inboxFiles){
                if(tmp3.isDirectory())
                    continue;                       
                readNPrase(tmp3, new File("/media/ADATA SH12/datasets/parsedEnron/"+temp.getName()+tmp3.getName()+".txt"));                         
            }
        }
    }   

}

函数readNParse的作用是:

public void readNPrase(File in,File out){
    BufferedReader br=null;
    BufferedWriter bw =null;
    try{
        br = new BufferedReader(new FileReader(in));
        bw= new BufferedWriter(new FileWriter(out));
        boolean messageContent = false;
        String line = null;
        while((line = br.readLine()) != null){              
            if(line.trim().equals(""))
                messageContent = true;
            if(messageContent && !isHeader(line) && !line.trim().equals("")){
                bw.write(line);
                bw.newLine();
            }

        }
            bw.flush();
            br.close();
            bw.close();
    } catch (IOException e) {
        e.printStackTrace();
    }finally{
        try{
            bw.close();
            br.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

在运行此代码10分钟后,它停止工作并给出以下错误:

java.lang.NullPointerException java.io.FileNotFoundException: /media/ADATA SH12/datasets/parsedEnron/causholli-m98.txt (No space left on device)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
at java.io.FileOutputStream.<init>(FileOutputStream.java:171)
at java.io.FileWriter.<init>(FileWriter.java:90)
at EnronMailParser.readNPrase(EnronMailParser.java:16)
at EnronMailParser.getInboxFiles(EnronMailParser.java:71)
at EnronMailParser.main(EnronMailParser.java:84)

我检查了硬盘空间,但有太多空闲空间。 一些人说这与文件名有关,而另一些人则认为这与inode有关,后者是一个操作系统问题。我不知道这是什么,也不知道如何解决。我使用的是Ubuntu 12.04。


如果运行了10分钟,那么您正在处理的树中必须有相当大量的文件,然后将解析版本全部写入一个目录(因此将该树展平),因此可能会耗尽空间或达到文件数量限制。在失败后,您能否查看/media/ADATA SH12/datasets/parsedEnron中有多少个文件以及/media文件系统上的剩余空间(df -k)? - dethorpe
2个回答

12
正如您所提到的,“No space left on device”可能意味着您在新文件将存储的文件系统中的索引节点已用完。Unix文件系统(包括Ubuntu)通常为文件系统中存储的每个文件使用称为“inode”的数据结构。当创建文件系统时,索引节点的数量是固定的,并且它限制了可以在文件系统中创建的文件数量。如果文件系统的索引节点用完了,则即使有空间也无法创建新文件。
您可以运行“df -i”命令来查看每个文件系统具有多少索引节点以及有多少可用。
文件系统通常会创建许多索引节点,因此很少出现用尽的情况。该文件系统可能有大量非常小或空的文件。通常会发现某些程序在某个不起眼的目录中悄悄地创建了空文件。您应检查文件系统以查看是否有一些可以删除的文件。请记住,您要寻找大量需要删除的文件,因为您想释放大量索引节点。每个文件的大小并不重要。
如果文件系统的索引节点用完了,则在程序内部解决此问题的选择不多。如果您的程序是创建了一堆空文件的那个程序,则应重新考虑程序的工作方式。否则,您唯一的选择就是在没有索引节点问题的其他地方创建文件。

4

大多数文件系统都有单个目录中可以包含的文件数量限制。我猜您已经达到了这个限制。我建议添加一些目录嵌套级别,以便所有结果文件不会最终存储在同一个目录中。这里有一些限制信息:https://dev59.com/iXRB5IYBdhLWcg3w7reV#466596


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接