`
wtt2312
  • 浏览: 14075 次
  • 性别: Icon_minigender_2
最近访客 更多访客>>
社区版块
存档分类
最新评论

黑马程序员---IO流(1)

 
阅读更多
  
-------http://www.itheima.comjava培训、android培训期待与您交流!------- 


   IO流是用来处理设备之间的数据传输。简单的说,就是对一些文件的操作,文本、图片或媒体文件等。而java对数据的操作时通过流的方式实现的,这些用于操作流的对象都在IO包中。流按流分为输入流和输出流,按照操作数据的方式分为字节流和字符流。
    一般来讲,字节流主要是处理媒体数据的(如MP3、stormplayer等)。
                     抽象基类(父类):InputStream、OutputStream
              字符流主要是对文本文件数据的操作。
                     抽象基类:Reader、Writer
一般父类名作为子类名的后缀,而前缀名则是该流对象的功能。数据的最常见的体现方式为文件。  
一、字符流的相关操作:
1、
FileWriter:用于在硬盘上向文本文件中写入文字数据。   
      步骤:
      (1)创建对象(该对象一旦被初始化,就必须要明确被操作的文件,也就是要明确数据要存放的路径[/size])
      (2)调用FileWriter的writer()方法将数据写入
      (3)刷新流对象中的缓冲区中的数据(写入一次,刷新一次)
      (4)关闭流资源(关闭之前会刷新一次内存)
   区别:
      flush():刷新后流可继续使用
      close();刷新后流关闭
需要注意的是,在文件创建的时候,系统调用的是底层资源,这时会发生异常。所以,要添加处理异常方式。try{}catch(){}finally{}(必须要关闭资源)
部分代码如下:
      
//创建对象引用,并初始化为null(或者FileReader fr ;)
		FileReader fr = null ;
		try
		{
			//创建要写入和读取的文件
			fw = new FileWriter("f:\\filecopy_2.txt");
                        fw.write("你好吗?");
		}
		catch (IOException e)
		{
			System.out.println(e.toString);
		}
		finally
		{
			if (fw!=null)
			{
				try
			{
					fw.close();[/align]
				
			}catch (IOException e) 
			{	
			}
		  }
		}

  文件的续写:FileWriter(File file, boolean append)
将指示是否附加写入数据的 boolean 值设定为true,则在已有数据末尾处添加数据。
即:FileWriter fw = new FileWriter("1demo.txt",true);
       fw.write("wangting");
   
FileReader:用于从文本文件中读取数据。
     如:将c盘的一个文本文件复制到d盘(FileWriter和FileReader)
     步骤:
     (1)在d盘新建一个文本文件,用于存储接收的c盘文本文件数据
     (2)创建一个关联文件用于复制
     (3)定义一个字符数组,用于读写要复制的数据(异常处理)
     (4)关闭资源 fw fr
//从c盘读取一个字符就往f盘写入一个字符
	public static void copy_1() throws IOException
	{
		//创建复制的路径
		FileWriter fw = new FileWriter("f:\\demo_copy.txt");
		//创建一个文件关联(要复制的文件数据路径)
		FileReader fr = new FileReader("c:\\demo.txt");

		int ch = fr.read();

		while (ch!=-1)
		{
			fw.write(ch);
		}

		fw.close();
		fr.close();
	}

	//从c盘读取一个字符数组,就往f盘写入一个字符数组
	public static void copy_2()
	{
		//创建对象引用,并初始化为null(或者FileReader fr ;)
		FileReader fr = null ;
		FileWriter fw = null;

		try
		{
			//创建要写入和读取的文件
			fw = new FileWriter("f:\\filecopy_2.txt");
			fr = new FileReader("c:\\demo.txt");
			
			
			//定义一个字符数组,用于读写数据
			char[] buf = new char[1024];

			int len = 0;
			while ((len = fr.read(buf))!=-1) //若读入的字符数不为-1
			{
				fw.write(buf,0,len);  //将缓冲区中的数据写入f盘下的filecopy_2.txt
			}
		}
		catch (IOException e)
		{
			throw new RuntimeException("读取失败");
		}
		finally
		{
			if (fw!=null)
			{
				try
			{			
					fw.close();				
			}catch (IOException e) 
			{				
			}
		  }
			if (fr!=null)
			{
				try
				{
					fr.close();
				}
				catch (IOException e)
				{					
				}
                    }		
		}		

2、字符流缓存区,用于提高对数据的读写效率。
BufferedWriter:
     步骤:
              (1)创建写入流对象(字符流缓冲区只有结合流才能使用)
                    FileWriter fw = new FileWriter("demo.txt");
              (2)创建字符流缓冲对象,将需要被提高效率的流对象作为参数传递给缓冲区的构造函数            
                   BufferedWriter bufw = new BufferedWriter(fw);
              (3)刷新缓冲区(只要用到缓冲区就要刷新)
                     bufw.flush();
              (4)关闭缓冲区(也就是关闭流资源)
                      bufw.close();
              bufw.newLine():跨平台换行符

BufferedReader:
        步骤:
                (1)创建读取流对象并关联文件
                       FileReader fr = new FileReader("demo.txt");
                (2)创建缓冲区对象,将流对象作为参数传递给缓冲区的构造函数
                      BufferedReader bufr = new BufferedWriter(fw);
                (3)读取数据(课一行行的读,且返回类型为String)
                      String s= null;
                      while ((s=bufr.readLine())!=-1){System.out.println(s);}
                (4)关闭缓冲区资源
                      bufr.close();
3、装饰设计模式
使原有功能增强(在字符流缓冲区的读取方式上,一行行的读取比一次读取一个字符更加高效,但是一行行的读取是基于read方法的,readLine方法就是对read方法的增强)。
当想要对已有的对象进行功能增强时,可以定义类将已有对象作为参数传递给自定义的构造函数,基于已有功能并提供加强功能,那么自定义类就成为装饰类。
字符流缓冲区中的readLine()方法就是对read()方法功能的增强。
/*
模拟readLine()方法
基于read方法,自定义与readLine方法一致的方法
*/
import java.io.*;
//将该功能封装到一个类中
class MyBufferedReader extends Reader
{ 
	//使用的是FileReader类中的基本方法
	//定义一成员变量,作用于整个类
	private Reader r;
	//该对象一初始化就可以接收一个流对象
	MyBufferedReader(Reader r)
	{
		this.r = r;
	}
	//对外提供一个自定义方法,用于读取数据(一行一行的读)
	public String myReadLine() throws IOException
	{
		//定义一个临时容器,原BufferedReader封装的是字符数组
		//定义一个StringBuilder容器,因为最终还是将数据转换成字符串
		StringBuilder sb = new StringBuilder();

		int ch = 0;
		while ((ch=r.read())!=-1)
		{
			if (ch=='\r')
				continue;
			if (ch=='\n')
				return sb.toString();
			else 
				sb.append((char)ch);
					
		}
		//由打印结果来看,最后数据的后面有一个换行符,如果将换行符去掉,
		//则最后一行数据就会丢失,所以判断一下
		if (sb.length()!=0)
			return sb.toString();
		
		return null;
	}


	/*
	自定义装饰类只要继承reader,并复写reader中的抽象方法即可
	*/
	public void close() throws IOException
	{
		r.close();
	}
	public int read(char[] cbuf, int off, int len)
	{
		return read(cbuf, off,len);
	}

	//自定义关闭流资源动作
	public void myClose() throws IOException
	{
		//其实,缓冲区的底层就是调用了流的关闭动作
		r.close();
	}
	public static void main(String[] args)  throws IOException
	{
		/*这里要写明文件的具体位置,若不指定盘符,则默认在当前目录下F:\java\day19寻找,
		若找不到,报异常
		F:\java\day19>java MyBufferedReader
		Exception in thread "main" java.io.FileNotFoundException: 123.txt (系统找不到指
		定的文件。)
		*/
		FileReader fr = new FileReader("f:\\123.txt");
		MyBufferedReader myBufR = new MyBufferedReader(fr);

		String line = null;
		while ((line=myBufR.myReadLine())!=null)
		{
			System.out.println(line);
		}
		myBufR.myClose();

	}
}

装饰类和继承的区别:
装饰类将原有继承体系优化,装饰类的设计使其变得更加灵活,避免的继承体系的臃肿,降低了类与类之间的关系。
装饰类和被装饰类通常都属于一个体系中。
4、LineNumberReader设置、获取行号
import java.io.*;
class LineNumberReaderDemo 
{
	public static void main(String[] args) throws IOException
	{
		FileReader fr = new FileReader("BufferedDemo.java");
		LineNumberReader lnr = new LineNumberReader(fr);

		String line = null;
		//行号从201开始
		lnr.setLineNumber(200);
		while ((line=lnr.readLine())!=null)
		{
			System.out.println(lnr.getLineNumber()+"::"+line);
		}

	}
}


二、字节流的相关操作
字节流主要用于存储字节数据。
InputStream:读取流
OutputStream:写入流

1、字节流的读写操作
       //一次写入一个字节
		public static void writeFile() throws IOException
		{
			//默认情况下在当前目录下  f:\\java\\day19
			FileOutputStream fos = new FileOutputStream("1.txt");
			
			//将字符串转成字节
			fos.write("wangtingting".getBytes());

			//关闭资源  不必刷新
			fos.close();

			//为什么在1.txt中写入数据后再编译时,写入的数据消失?
		
		}
	
		//一次读取一个字节
		public static void readFile_1() throws IOException
		{
			FileInputStream fis = new FileInputStream("1.txt");

			int ch = 0;
			while ((ch=fis.read())!=-1)
			{
				System.out.println((char)ch);
			}
			fis.close();			

		}
		//一次读取一个字节数组
		public static void readFile_2() throws IOException
		{
			FileInputStream fis = new FileInputStream("1.txt");

			byte[] buf = new byte[1024];
			int len = 0;
			while ((len=fis.read(buf))!=-1)
			{
				System.out.println(new String(buf, 0, len));
			}
			fis.close();
	
		}
		public static void readFile_3() throws IOException
		{
			FileInputStream fis = new FileInputStream("1.txt");
			//int num = fis.available();

			byte[] buf = new byte[fis.available()];//定义一个刚刚好的缓冲区 不用   再循环了

			fis.read(buf);
			System.out.println(new String(buf));

			
			//System.out.println("num = "+num);//若在文本中自定义输入一个字节q,则 num = 15  说明换行符占两个字节

			fis.close();
		}


2、拷贝MP3文件:通过字节流缓冲区复制MP3文件,提高读写效率。
public static void main(String[] args)  throws IOException
	{
		long start = System.currentTimeMillis();
		copyMp3();
		long end = System.currentTimeMillis();

		System.out.println(end - start);
	}

	public static void copyMp3() throws IOException
	{
		//要复制的路径
		BufferedOutputStream bufos = new  BufferedOutputStream(new   FileOutputStream("你那么爱他.mp3"));
		//被复制的MP3
		BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("李圣杰林隆璇 - 你那么爱她.mp3"));

		byte[] buf = new byte[1024];
		int len = 0;
		while ((len=bufis.read(buf))!=-1)
		{
			bufos.write(buf,0,len);
		}
		bufos.close();
		bufis.close();
	}

当然,我们这里要进行异常处理,所以简单的将异常抛出了。
3、拷贝图片文件
下面我们写一个规范的复制文件代码:
public static void main(String[] args) 
	{
		//初始化为空
		FileInputStream fis = null;
		FileOutputStream fos = null;

		try
		{
			//创建文件读取字节流对象并明确要复制的图片路径
			fis = new FileInputStream("2.jpg");
			//创建文件写入字节流对象,用于图片复制的地方
			fos = new FileOutputStream("copy.jpg");

			//定义一个字节数组
			byte[] buf = new byte[1024];

			int len = 0;
			while ((len= fis.read(buf))!= -1)
			{
				fos.write(buf,0,len);
			}
		}
		catch (IOException e)
		{
			throw new RuntimeException("读写失败");//抛出新建异常对象
		}
		finally 
		{
			try
			{
				if (fis!=null)
					fis.close();
			}
				catch (IOException e)
			{
				throw new RuntimeException("读取失败");
			}
			try
			{
				if (fos!=null)
					fos.close();
			}
				catch (IOException e)
			{
				throw new RuntimeException("写入失败");
			}
		}
	}


4、读取键盘录入
System.out:对应的是标准输出设备--->控制台
System.in:对应的是标准输入设备--->屏幕
键盘录入要有结束标记,否则程序不能结束,只有强制结束:ctrl+c
/*
键盘录入的方式获取数据

System.out:对应的是标准的输出设备  控制台
System.in:输入设备 键盘

*/
import java.io.*;
class ReadIn 
{
	public static void main(String[] args) throws IOException
	{
		InputStream in = System.in;

		//键盘录入一个字符,就将该数据存储起来,因为长度不确定故用StringBuilder
		StringBuilder sb = new StringBuilder();
		 while (true)
		 {
			 int ch = in.read();
			 //如果读到\r,程序继续
			 if (ch=='\r')
				 continue;
			 if (ch=='\n')
			 {
				 //如果读到\n,将数据转换成字符串,再转换为大写输出
				 String s = sb.toString();
				 //读到over,程序停止
				 if ("over".equals(s))
					 break;
				 System.out.println(s.toUpperCase());
				 //每次录入都要讲缓冲区清空
				 sb.delete(0,sb.length());
			 }
			 //忘记写else ,录入后空一行再转换为大写,且程序不能停止
			 else
				 sb.append((char)ch);
			 			 
		 }

		/*
		int ch = 0;
		while ((ch=in.read())!=-1)
		{
			System.out.println(ch);
		}
		也可不管资源,录入结束程序结束
		in.close();
		*/

		/*只能键入一次
		回车符也是字节\r 13 	\n 10

		int by = in.read();
		int by1 = in.read();
		int by2 = in.read();
		System.out.println(by);
		System.out.println(by1);
		System.out.println(by2);
		
		System.out.println('\r'+0);
		System.out.println('\n'+0);

		*/

		
	}
}


5、读取/写入转换流
通过刚才的键盘录入一行并打印其大写,发现其实就是读一行的原理,
也就是readLine方法
能不能直接使用readLine方法来完成键盘录入?
readLine是字符流BufferedReader类中的方法,
而键盘录入的read方法时字节流InputStream的方法
字节流-->字符流????
import java.io.*;
class TransStreamDemo 
{
	public static void main(String[] args) throws IOException
	{
		//获取键盘录入对象
		InputStream in = System.in;

		//将字节流对象转成字符流对象,将字节流作为参数传递给转换流的构造函数
		InputStreamReader isr = new InputStreamReader(in);

		//字节流->字符流,就可以用字符流的操作规律操作,缓冲区技术
		//将要被提高效率的流对象传递给BufferedReader的构造函数
		BufferedReader bufr = new BufferedReader(isr);
		
		[b]//键盘录入最常见写法
		//BufferedReader bufr = 
		//	new BufferedReader(new InputStreamReader(System.in));[/b]

                //写入转换流

		OutputStream out = System.out;
		OutputStreamWriter osw  = new OutputStreamWriter(out);
		BufferedWriter bufw = new BufferedWriter(osw);

		[b]//BufferedWriter bufw = 
		//	new BufferedWriter(new OutputStreamWriter(System.out));[/b]
		
		String line = null;
		while ((line=bufr.readLine())!=null)
		{
			
			if ("over".equals(line))
				break;
			
			bufw.write(line.toUpperCase());
			//newLine方法是BufferedWriter的方法,所以要将写入转换流装饰一下
			bufw.newLine();
			//若不刷新,没有数据
			bufw.flush();
		}
		bufr.close();

		/*
		//转换完成,可以字符流的特点读取
		String line = null;
		while ((line=bufr.readLine())!=null)
		{
			//如果读到结束标记,则程序停止
			if ("over".equals(line))
				break;
			
			//如果不判断结束标记程序不会停下来,只有强行停止 ctrl+c
			System.out.println(line.toUpperCase());
		}
		bufr.close();
		*/
	}
}

6、流操作规律
对于流的操作只要明确源和目的就行。比如:
键盘录入:
源:键盘录入  目的:控制台
将键盘录入的数据写到一个文件中:源:控制台 目的:文件
将一文件种的数据打印到控制台 源:文件 目的:控制台

流操作规律:
(1)明确源和目的
源:输入流 InputStream  Reader
目的:输出流 OutputStream Writer
(2)操作的数据是否是纯文本
是:字符流
不是:字节流
(3)当体系明确后,再明确要使用哪个具体对象
可以通过设备区分:
源设备:内存(ArrayStream)、硬盘(FileStream)、键盘(System.in)
目的设备:内存(ArrayStream)、硬盘(FileStream)、控制台(System.out)
7、
可以通过set方法改变输入或输出设备。


因为该类System中的方法都是静态的,所以直接调用即可。

8、异常日志信息/系统信息
异常日志信息:
我们在编写程序时,为了测试功能是否健全,会直接将信息打印在控制台上,但是在实际开发中,不可能说当用户使用产品的时候出现的问题直接打印给用户看,所以,这时就需要将这些出现的问题存储到一个文件中,方便程序员及时查看做出适当的解决方案。
import java.io.*;  
import java.util.*;  
import java.text.*;  
  
class ExceptionInfo  
{  
    public static void main(String[] args){  
        try{  
            int[] arr = new int[2];  
            System.out.println(arr[3]);  
        }catch (IOException e){  
            try{  
                Date d = new Date();  
                SimpleDateFormat sfd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
                String s = sfd.format(d);  
  
                PrintStream pf = new PrintStream("exception.log");  
                pf.println(s);  
                System.set(ps);  
            }  
            catch (IOException ex){  
                throw new RuntimeException("日志文件创建失败。");  
            }  
            e.printStackTrace(System.out);  
        }  
    }  
}  


系统信息:
System类中的获取当前系统属性方法:getProperties()
Properties类中的方法list(PrintStream out) : 将属性列表输出到指定的输出流。
import java.util.*;  
import java.io.*;  
  
class SystemInfo   
{  
    public static void main(String[] args)   
    {  
        PrintStream ps = null;  
        try  
        {  
            //获取系统信息:  
            Properties pop = System.getProperties();  
            //创建输出流对象,将输出流中数据存入指定文件中  
            ps = new PrintStream("systeminfo.txt");  
            //将属性列表输出到指定的输出流  
            pop.list(ps);  
        }  
        catch (Exception e)  
        {  
            throw new RuntimeException("获取系统信息失败。");  
        }  
    }  
}  


三、File
1、File类:文件和目录路径的抽象表现形式
特点:
1)用来将文件或文件夹封装成对象
2)方便于对文件与文件夹的属性信息进行操作
3)File对象可以作为多数传递给流的构造函数
2、File常见操作
创建File对象:
public static void sop(Object obj)
	{
		System.out.println(obj);
	}


//构造方法 字段
    public static void constructionMethod()
	{
		//将file.txt作为参数传递给File对象  
		File f1 = new File("filedemo.txt");//相对路径

		File f2 = new File("f:\\java\\day20","demo.txt"); //绝对路径
		//File ff = new File("f:\\java\\day20\\demo.txt");  f2和ff指的的同一个文件
		//可以将demo.txt写成变量    File f2 = new File("f:\\java\\day20",str); 
		
		File fi = new File("f:\\java\\day20");
		File f3 = new File(fi,"demo3.txt");
		
		//封装的是什么打印的就是什么路径
		sop("f1:"+f1);
		sop("f2:"+f2);
		sop("f3:"+f3);
		
		//跨平台分隔符  可以用“/”
		File f4 = new File("f:"+File.separator+"java"+File.separator+"day19/demo.txt");
		sop("f4:"+f4);

	}


File的常见构造方法:
//创建
	public static void method_1() throws IOException
	{
		//在当前目录下创建一个新文件,若文件已存在,则不允许再创建
		File f = new File("file.txt");

		sop("createNewFile:"+f.createNewFile());
		//删除失败 返回false
		sop("delete:"+f.delete());

		//sop("deleteOnExit::"+f.deleteOnExit());在退出时删除  一般用于临时文件删除

	}


//判断
	public static void method_2() throws IOException
	{
		File f = new File("java.txt");
		f.createNewFile();
		sop("exists---"+f.exists());
		sop("是否双击可执行----"+f.canExecute());
		sop("是否可读------"+f.canRead());
		sop("是否可写------"+f.canWrite());

		sop("是否是绝对路径----"+f.isAbsolute());
		sop("是否是一个目录----"+f.isDirectory());

		//在判断文件对象是否是文件或目录时,必须先判断该文件是否存在,用exists();
		sop("是否是文件----"+f.isFile());
		sop("是否是隐藏的----"+f.isHidden());

		sop("----------------------------------");
		
		File f1 = new File("1.txt");
		//创建一级目录
		sop(f1.mkdir());
		File f2 = new File("f:\\java2\\java\\1.txt");
		//创建多级目录
		sop(f2.mkdirs());



	}


//获取信息
	public static void method_3() throws IOException
	{
		File f1 = new File("f:\\java\\day20\\inquire.txt");
		File f2 = new File("inquire.txt");

		sop(f2.getPath()+"---"+f1.getPath());
		sop(f1.getAbsolutePath());//返回绝对路径   f:/java/day20/inquire.txt
		sop(f2.getParent());//若没有指定父目录则返回null  若运行f1 则返回 f:/java/day20
		
		File f3 = new File("f:\\java\\day20");

		sop(f3.lastModified());//返回最后一次修改的时间  

		sop(f3.length());//返回文件的长度
		
		//sop(f.createNewFile());
	}

//方法摘要
	public static void method_4()throws IOException
	{	
		File f =new File("f:\\java\\day20");
		//列出该目录下的所有文件
		File[] file= f.listFiles();

		for (File  name : file )
		{
			
			System.out.println(name);
		}		
		
	}

3、文件列表
相关的操作方式:
(1)static File[] listRoots():列出机器中的有效盘符(列出可用的文件系统根)
                      static (不需要创建对象): 不操作文件的特有数据,操作共享数据
                      且返回类型为 File[] 文件数组
                      作用(什么时候使用):当想要把程序安装到某个盘符中时。
(2)String[] list():用于列出当前目录下的所有文件(包括隐藏的文件)
            file对象必须是封装了一个目录,该目录还必须是存在的
                    比如:File f = new File("f:\\java\\avc.txt"); 则空指针异常

(3)String[] list(FilenameFilter filter) : 文件名过滤
    FilenameFilter:是一个接口。。
            实现此接口的类实例可用于过滤器文件名接口中的方法只有一个:
           boolean accept(File dir, String name) 测试指定文件是否应该包含在某一文件列表中。
           File dir:表示文件的目录
           String name:表示目录下的文件名称
(4) File[] listFiles():返回的是File对象,那么就可以调用getName等方法
而String[] list();返回的是文件目录名称

import java.io.*;
class  FileDemo2
{
	public static void main(String[] args) 
	{

		listFilesDemo();
	}
	public static void listFilesDemo()
	{
		//创建一个目录对象,用于遍历该目录下的文件
		File dir = new File("f:\\java");
		
		//列出该目录下的文件,并返回File[]类型
		File[] files = dir.listFiles();
		
		//由于该方法返回的是数组对象,所以,数据类型是File对象
		for (File f : files )
		{
			System.out.println(f.getName()+"---"+f.length());
		}

	}

	public static void filterDemo()
	{
		File dir = new File("f:\\java");
		//实现FilenameFilter接口,并覆盖其中的accept方法
		String[] arr = dir.list(new FilenameFilter()
		{
		  public boolean accept(File dir,String name)
			{
			
			  return name.endsWith(".java");
			  /*
			  //dir打印的是 f:/java 目录,name 打印的是该目录下的文件名
			  System.out.println(dir+"----"+name);

			  if (name.endsWith(".java"))
			  {
				  return true;
			  }
			  else
				return false;
				*/
			}
		});

		for (String names : arr )
		{
			System.out.println(names);
		}
	}
	
	public static void listDemo()
	{
		//打印出f:/java/下的所有文件和目录
		File f = new File("f:\\java\\");
		String[] names = f.list();

		for (String name : names)
		{
			System.out.println(name);//写names是不对的 
			
		}

		
	}
	public static void listRootsDemo()
	{	
		File[] files = File.listRoots();

		//遍历          
		//高级for循环		格式:for(数据类型 变量名 : 要操作(遍历)的集合或数组){   打印变量 }
		//name 也可以是f
		for (File f : files)
		{
			System.out.println(f);
		}


	}
}


4、列出目录下的所有内容(递归)
递归:调用自身方法。
如该实例,需要列出目录下的所有内容,也就是说文件夹1下有文件夹2,文件夹2下有文件,要遍历多级目录。在遍历多级目录的时候,使用的方法就是遍历一级目录的方法。
递归注意事项:
(1)要限定条件,是作为结束循环用的,否则是死循环。
(2)限定递归次数(如果递归的次数过多,栈内存中的某些方法还没有执行完就继续向下执行,会导致内存不够,即内存溢出)。
/*
列出目录下的所有内容(递归)
*/
import java.io.*;
class  FileDemo3
{
	public static void main(String[] args) 
	{
		
		//创建一个目录,用于遍历其中的文件夹
		//必须在主函数中创建
		File dir = new File("f:\\java\\day20");
		showDir(dir);
	}

	//定义一个功能,用于遍历文件夹(文件夹下包含文件,也就是遍历多级目录)
	public static void showDir(File dir)  //接收一个目录,用于列出该目录下的文件
	{
		//打印一下目录
		System.out.println(dir);
		
		//调用listFiles()方法,用于列出该目录下的文件(files),其返回类型为	File[]	数组对象
		File[] files = dir.listFiles();
		
		for (int x =0; x<files.length;x++ )
		{
			//如果该文件是目录的话,
			if (files[x].isDirectory())
			{
				//再遍历该目录下的文件   方法中调用自身方法
				showDir(files[x]);
			}
			else 
			System.out.println(files[x]);

		}
		
		
		//高级for循环
		for (File f : files )
		{
			if (f.isDirectory())
			{
				showDir(f);
			}
			else
			System.out.println(f);
		}
	}
}

5、创建java文件列表
将一个指定目录下的java文件的绝对路径存储到一个文本文件中,建立一个文件列表。
如:f:\\java\\day20\\xxx.java  ---->   \\xxx.txt文件
步骤:
(1)对指定的目录进行递归
(2)获取递归过程中所有java文件的绝对路径
(3)将遍历的绝对路径存储到一个集合中
(4)将集合中的数据写入到一个txt文本文件中
import java.io.*;
import java.util.*;
class  JavaFileList
{
	public static void main(String[] args)  throws IOException
	{
		File dir = new File("f:\\java\\day20");

		List<File> list = new ArrayList<File>();

		fileToList(dir,list);

		File file = new File(dir,"javalist.txt");
		listToFile(list,file.toString());


		//System.out.println(list.size());
		
	}
	//定义一个功能(方法)用于遍历指定目录,将获取的绝对路径存到集合中
	public static void fileToList(File dir,List<File> list)
	{
		//调用listFiles()方法,用于列出目录下的文件
		File[] files = dir.listFiles();
		
		//f表示每遍历一次打印的路径(是变化的)  files 表示列出的所有目录
		for (File f : files )
		{
			//如果该文件时目录,则遍历该目录
			if (f.isDirectory())
			{
				fileToList(dir,list);
			}else  
			{
				//如果该文件不是目录,且后缀名为java,将该路径存储到集合中
				if (f.getName().endsWith(".java"))
				{
					list.add(f);
				}
			}
			
		}
	}
	//定义一个方法,用于将获取的集合存储到一个文本文件中
	//将数据复制到文本文件中,FileWriter ,要提高效率,则用字符流的缓冲区 BufferedWriter
	public static void listToFile(List<File> list,String javaListFile) throws IOException
	{
		BufferedWriter bufw = null;
		try
		{
			bufw = new BufferedWriter(new FileWriter(javaListFile));
			for (File f : list )
			{
				String path = f.getAbsolutePath();
				bufw.write(path);
				bufw.newLine();
				bufw.flush();
			}
			
			
		}
		catch (IOException e)
		{
			throw e;
		}
		finally 
		{
			try
			{
				if (bufw != null)
					bufw.close();
			}
			catch (IOException e)
			{
				throw e;
			}
		}
	}
}






-------http://www.itheima.comjava培训、android培训期待与您交流!-------
  • 大小: 7.9 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics