黑马程序员技术交流社区

标题: 求解:在盘符中搜索文件(listFiles())出现NullPointerException [打印本页]

作者: yufeng47    时间: 2013-3-27 10:07
标题: 求解:在盘符中搜索文件(listFiles())出现NullPointerException
/*
求解:关于在盘符中搜索文件(listFiles()方法)出现NullPointerException

需求:通过键盘将一个指定目录下的所有指定格式文件(如.java、avi)的绝对路径,
      存储到一个文本文件中。建立一个java文件列表文件。
   键盘的录入格式为:
  1、父级目录-文件名/文件格式/字段\r\n文件名/文件格式/字段\r\n文件名/文件格式/字段......
       父级目录-文件名/文件格式/字段\r\n父级目录\r\n父级目录\r\n父级目录......
   如:f:/text-txt
         c:\\music\list-我的心好冷.mp3
         e:\-.java    (遍历 e 盘中带字段 .java 的文件)
         doc
         .dll
         d:\
  2、文件名/文件格式/字段 父级目录\r\n文件名/文件格式/字段\r\n文件名/文件格式/字段......
       文件名/文件格式/字段 父级目录\r\n父级目录\r\n父级目录\r\n父级目录......
思路:
1、通过键盘输入指定目录和文件字段。
2、对指定的目录进行递归。
3、获取递归过程中所有的java文件的路径。
4、将这些路径存储到集合中。
5、将集合中的数据写入到一个文件中。
步骤:
1、定义类SearchFile,查找某文件夹中的文件。
2、提供对外访问方法search。
3、定义方法inputDir,使用键盘写入数据,需要InputStreamReader转换流来将字节数据转换成字符串数据。
4、定义方法spiltString,来区分输入的字符串中的目录和文件字段。
5、定义方法fileToList,对指定目录递归,将遍历到的所有目录存入数组files中,
   并将所有遍历到的绝对目录添加到list集合中。
6、定义方法writeFile,通过输出流 BufferedWriter 将获取的绝对路径写入指定的 .txt文件中。
注:尽量缩小盘符查找,过大容易报异常。

question:在进行全盘遍历的时候,有些盘遍历一会儿后会报 NullPointerException,
    偶尔运行又是正常的,怎么解决?
    该异常发生在fileToList()的循环体中。
    如:f:\-dll     c:\-exe
*/

import java.util.*;
import java.io.*;

class SearchFile
{
private String filetype;  //指向文件类型的成员变量
private String directions;   //指向一行字符串的成员变量
//该功能实现了使用键盘输入需要查找的文件夹中的某/某类型文件
public void search()
{
  inputDir();
}
private void inputDir()
{
  BufferedReader bufr = null;  //声明空输入流
  List<File> list = null;   //声明空list集合
  try
  {
   //使用转换流 InputStreamReader,将键盘录入的字节流数据转换成字符流数据来处理
   bufr = new BufferedReader(new InputStreamReader(System.in));
   //集合中的数据要在最后一步进行清空,否则最后数据越积越多。
   list = new ArrayList<File>();
   String line = null;
   //获取键盘输入的一行字符串,并判断是否为空。
   while ((line=bufr.readLine())!=null)
   {
    if ("over".equals(line))
     break;
    else
    {
     //切割line字符串,并将切割后的子串分别存入files数组中
     spiltString(line);
     System.out.println("路径: "+directions+"--------文件类型: "+filetype);
     File dir = null;   
     try
     {
      //将键盘输入数据作为值传递给该文件类对象,若引用file指向空则报异常
      dir = new File(directions);
     }
     catch (NullPointerException e)
     {
      throw new NoSuchFileException("目录不存在!");
     }
     fileToList(dir,list,filetype); //throws NullPointerException
     consFile(list,filetype);
    }   
   }
  }
  catch (IOException e)
  {
   throw new NoSuchFileException("文件名格式书写错误!");
  }
  finally
  {
   try
   {
    if (bufr!=null)
     bufr.close();
   }
   catch (IOException e)
   {
    throw new RuntimeException("输入流关闭失败!");
   }
  }
}
//功能实现了将路径存入集合中
private void fileToList(File dir, List<File> list, String filetype) throws NullPointerException
{
  //遍历文件夹中的文件和子文件夹,将遍历的目录(包括父目录和绝对目录)作为对象存入数组中
  File[] files = dir.listFiles();
  //高级for循环,迭代File[]数组,将其中的目录依次赋值给f
  for (File f : files)
  {
   //获取的file值是目录就继续递归,否者就将file文件存入List集合中
   if (f.isDirectory())
    fileToList(f,list,filetype);
   else if (f.getName().contains(filetype))
    list.add(f);
   //System.out.println("file: "+f);
  }
}
//创建文件
private void consFile(List<File> list, String filetype)
{
  FileWriter fw = null;
  try
  {
   fw = new FileWriter("f:"+File.separator+filetype+".txt");
   //调用写入数据方法
   write(fw,list,filetype);
  }
  catch (IOException e)
  {
   //System.out.println("路径为:"+"f:"+File.separator+filetype+".txt");
   throw new NoSuchFileException("文件创建失败,请检查路径是否存在!");
  }
  finally
  {
   try
   {
    if (fw!=null)
     fw.close();
   }
   catch (IOException e)
   {
    throw new RuntimeException("输出流关闭失败!");
   }
  }
}
//向文件中写入数据
private void write(Writer writer, List<File> list, String filetype)
{
  //PrintWriter中的两个参数的意义:前者是将绝对路径封装成对象,并创建文件,会替换盖掉原文件。
  //true是:表示在每次向文件中写入数据时就刷新一次。separator:跨平台目录分隔符。
  PrintWriter out = new PrintWriter(writer,true);
  int count = 0; //定义计数器
  //高级for循环,迭代list集合,将其中的数据依次赋值给f
  for (File f : list)
  {
   //获取file文件的绝对路径
   String path = f.getAbsolutePath();
   out.println(path);
   count++;
  }
  out.println(); //换行,其实底层调用的就是newLine()
  out.write("一共有"+filetype+"文件"+count+"个");
  out.close(); //不需要进行处理,方法中已经处理过了
  //每遍历完一个文件夹(或最子文件夹)就清空一次集合,保证在下一次向集合中添加数据的有效性。
  list.clear();   
}
//切割字符串
private void spiltString(String line)
{
  String[] arr = new String[2];
  arr = line.split("-");
  for (int i=0; i<arr.length; i++)
  {
   File f = new File(arr);
   //判断目录是否存在,若不存在file变量让然为null。
   if (f.isDirectory())
    directions = f.toString();
   else
    filetype = f.toString();
  }
}
}
//自定义运行时异常类
class NoSuchFileException extends RuntimeException
{
NoSuchFileException(String message)
{
  super(message);
}
}
class  SearchFileDemo
{
public static void main(String[] args)
{
  SearchFile sf = new SearchFile();
  sf.search();  
}
}

作者: yufeng47    时间: 2013-3-27 21:34
肿么没人帮解哈啊  各位大神  帮个忙




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2