【问题标题】:java.io.FileNotFoundException and (No space left on device)java.io.FileNotFoundException 和(设备上没有剩余空间)
【发布时间】:2014-08-21 23:02:29
【问题描述】:

我有这个Java代码,它应该读取一个0.5M的文件并在删除一些无用的信息后写入(我正在使用安然电子邮件数据集)

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)

标签: java ubuntu file-io inode


【解决方案1】:

正如您所指出的,“设备上没有剩余空间”可能意味着您在存储新文件的文件系统上没有 inode。 Unix 文件系统(包括 Ubuntu)通常对存储在文件系统中的每个文件使用称为 inode 的数据结构。在创建文件系统时,inode 的数量是固定的,它限制了文件系统中可以创建的文件数量。如果文件系统的 inode 不足,即使有可用空间,您也无法创建新文件。

您可以运行df -i 来查看每个文件系统有多少 inode 以及有多少空闲。

文件系统通常是用大量 inode 创建的,所以用完有点不寻常。文件系统上可能有大量非常小的或空文件。发现某些程序一直在某个不起眼的目录中悄悄创建空文件的情况并不少见。您应该检查文件系统以查看是否有可以删除的文件。请记住,您正在寻找要删除的大量文件 ,因为您想要释放大量 inode。每个文件有多大都没有关系。

如果文件系统没有 inode,那么您在程序中就无法解决这个问题。如果您的程序是创建一堆空文件的程序,那么您应该重新考虑您的程序是如何工作的。否则,您唯一的选择是在 inode 不成问题的其他地方创建文件。

【讨论】:

    【解决方案2】:

    大多数文件系统对单个目录中的文件数量都有限制。我猜你已经达到了这个极限。我建议添加一些级别的目录嵌套,以便所有结果文件不会最终位于同一目录中。这里有一些限制信息:https://stackoverflow.com/a/466596/552759

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-29
      • 2012-01-14
      • 2012-05-15
      • 2018-11-22
      • 2015-07-21
      • 2020-12-16
      • 2014-11-20
      • 2018-12-27
      相关资源
      最近更新 更多