黑马程序员-基础-IO流(概念,File类,递归)

------- android培训java培训、期待与您交流! ----------

IO流 用于处理设备上的数据

流:可以理解为数据的流动,就是一个数据流。IO流最终要以对象来提现,对象都存在IO包中。

流的分类

1:输入流(读)和输出流(写)。

2:处理数据的不同,分为字节流和字符流。

字节流:处理字节数据的流对象。设备上的数据无论是图片或者DVD,文字,都是以二进制存储的。二进制的最终都是以一个8位为数据单元进行提现,所以计算机中的最小数据单元就是字节,意味着,字节流可以处理设备上所以数据,所以字节流一样可以处理字符数据。

为什么要有字符流呢

因为字符每个国家不一样,所以涉及到了字符编码问题,那么GBK编码的中文用unicode编码解析是有问题的,所以需要获取中文字节数据的同时+指定的编码表才可以解析正确数据。为了方便于文字的解析,所以讲字节流和编码表封装成对象,这个对象就是字符流。只能操作字符数据,优先考虑字符流

体系。

注意流的操作只有两种:读和写。

流的体系功能不同,但是有共性内容,不断抽取,形成继承体系。该体系一共有四个基类,而且都是抽象类。

字符流Reader   Writer

Reader:用于读取字符流的抽象类。子类必须实现的方法只有read(char[],int,int)和close();

      BufferedReader从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。 可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。

       LineNumberReader跟踪行号的缓冲字符输入流。此类定义了方法setLineNumber(int)getLineNumber(),它们可分别用于设置和获取当前行号。

       InputStreamReader是字节流通向字符流的桥梁:它使用指定的charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

       FileReader用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。要自己指定这些值,可以先在 FileInputStream 上构造一个 InputStreamReader。

Writer:写入字符流的抽象类。子类必须实现的方法仅有 write(char[],int, int)、flush() 和 close()。

       BufferedWriter将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

        OutputStreamWriter是字符流通向字节流的桥梁:可使用指定的charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。

        FileWriter用来写入字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是可接受的。要自己指定这些值,可以先在 FileOutputStream 上构造一个 OutputStreamWriter。

        PrintWriter

        CharArrayWriter

        StringWriter


字节流: InputStream   OutputStream

InputStream是表示字节输入流的所有类的超类。

       FileInputStream从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境。FileInputStream用于读取诸如图像数据之类的原始字节流。要读取字符流,请考虑使用 FileReader。

        FilterInputStream包含其他一些输入流,它将这些流用作其基本数据源,它可以直接传输数据或提供一些额外的功能。

         BufferedInputStream该类实现缓冲的输入流。

           Stream

        ObjectInputStream

        PipedInputStream

-----------------------------------------------

OutputStream此抽象类是表示输出字节流的所有类的超类。

          FileOutputStream文件输出流是用于将数据写入FileFileDescriptor 的输出流。

           FilterOutputStream此类是过滤输出流的所有类的超类。

          BufferedOutputStream该类实现缓冲的输出流。

          PrintStream

          DataOutputStream

           ObjectOutputStream

           PipedOutputStream


这四个系统中,他们的子类都有一个共性特点:子类名后缀都是父类名,前缀名都是这个子类的功能名称

第一节File类

第一:概念

File类:文件和目录路径的抽象表现形式

第二:特点

用于将文件或者文件夹封装成对象

方便对文件与文件夹的属性信息进行操作。

File对象可以作为参数传递给流的构造函数。


创建File对象:

方式1:File f1= new File("a.txt");//将a.txt封装成对象,可将已有和未出现的文件或文件夹封装成对象

方式2:File f2 = new File("c:\\abc","b.txt");//分别指定文件夹和文件。好处:降低了两者的关联程度

方式2:File d = new File("c:\\abc");     File f3 = new File(d,"c.txt");//可以传入父目录和文件名

目录分隔符:调用File.separator,方法如下

File f4 = new File("c:"+File.separator+"abc"+File.separator+"zzz"+File.separator+"a.txt");

第三:File类常见方法

1,创建。

 boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。

      和输出流不一样,输出流对象一建立创建文件。而且文件已经存在,会覆盖。

例子: File f = new File("file.txt");

sop("create:"+f.createNewFile());

  //sop("delete:"+f.delete());

 boolean mkdir():创建文件夹。

例子: File dir=new File("abc"); 

sop(dir.mkdir());//创建文件夹

 boolean mkdirs():创建多级文件夹。

例子: File dir=new File("abc\\cc\\bb\\aa\\gg"); 

sop(dir.mkdirs());//创建多层文件夹

2,删除。

 boolean delete()://删除成功返回true,删除失败返回false。如果文件正在被使用,则删除不了返回falsel。

 void deleteOnExit();在程序退出时删除指定文件。

3,判断。

 boolean exists() ://文件是否存在.存在返回true,不存在返回false

 isFile()://判断文件是否存在,存在返回true,不存在返回false

 isDirectory();//判断文件夹是否存在,存在返回true,不存在返回false

 isHidden();//测试是否是一个隐藏文件

 isAbsolute();//判断是否是绝对路径名

4获取信息

 getName()//获取文件名字

 getPath()//获取设置路径

 getParent()//该方法返回的是绝对路径中的文件父目录,如果获取相对路径,返回null

 getAbsolutePath() //获取绝对路径(如”D//java123//File。txt“即使文件不存在也能获取路径)   getAbsoluteFile()//获取绝对路径并封装成对象

 long lastModified() //返回最后一个被修改的时间

 long length() //获取文件的大小

static File[ ] listRoots()//获取文件的系统根,比如系统有c:  d:  e:等

String [ ] list()//列出当前目录所以文件,包含隐藏文件。注:调用了list方法的file对象,必须是封装了一个目录,而且目录必须存在。

boolean renameTo(File nihao)//对文件重命名为nihao

5,列出及过滤文件:

File[ ]list()//列出当前目录所以文件,包含隐藏文件。注:调用了list方法的file对象,必须是封装了一个目录,而且目录必须存在

File[ ]list(FilenameFilter filter)//FilenameFilter:文件名过滤器,是一个接口,其中包含一个方法,accept(File dir,String name)返回的是boolean类型,对不符合条件的文件过滤掉

File[ ]listFiles()//获取当前文件夹下的文件和文件夹,返回类型是File数组

ListFiles(FlenameFilter filter)//同list,是对获取的当前文件夹下的文件和文件夹的文件名过滤器。

代码事例如下

import java.io.*;

class FileDemo 

{

	public static void main(String[] args) throws IOException
	{
		method_5();
	}

	public static void method_5()
	{
		File f1 = new File("c:\\Test.java");
		File f2 = new File("d:\\hahah.java");

		sop("rename:"+f2.renameTo(f1));

	}

	public static void method_4()
	{
		File f = new File("file.txt");

		sop("path:"+f.getPath());
		sop("abspath:"+f.getAbsolutePath());
		sop("parent:"+f.getParent());//该方法返回的是绝对路径中的父目录。如果获取的是相对路径,返回null。
									//如果相对路径中有上一层目录那么该目录就是返回结果。



	}
	
	public static void method_3()throws IOException
	{
		File f = new File("d:\\java1223\\day20\\file2.txt");

		//f.createNewFile();

		//f.mkdir();


		//记住在判断文件对象是否是文件或者目的时,必须要先判断该文件对象封装的内容是否存在。
		//通过exists判断。
		sop("dir:"+f.isDirectory());
		sop("file:"+f.isFile());

		sop(f.isAbsolute());
	}


	public static void method_2()
	{
		File f = new File("file.txt");

		//sop("exists:"+f.exists());

		//sop("execute:"+f.canExecute());

		//创建文件夹
		File dir = new File("abc\\kkk\\a\\a\\dd\\ee\\qq\\aaa");

		sop("mkdir:"+dir.mkdirs());
	}
	

	public static void method_1()throws IOException
	{
		File f = new File("file.txt");
//		sop("create:"+f.createNewFile());
		//sop("delete:"+f.delete());



		
	}







	//创建File对象
	public static void consMethod()
	{
		//将a.txt封装成file对象。可以将已有的和为出现的文件或者文件夹封装成对象。
		File f1 = new File("a.txt");

		//
		File f2 = new File("c:\\abc","b.txt");


		File d = new File("c:\\abc");
		File f3 = new File(d,"c.txt");

		sop("f1:"+f1);
		sop("f2:"+f2);
		sop("f3:"+f3);

		File f4 = new File("c:"+File.separator+"abc"+File.separator+"zzz"+File.separator+"a.txt");


	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}

import java.io.*;

class  FileDemo2
{
	public static void main(String[] args) 
	{
		File dir = new File("c:\\");
		File[] files = dir.listFiles();

		for(File f : files)
		{
			System.out.println(f.getName()+"::"+f.length());
		}

		
	}

	public static void listDemo_2()
	{
		File dir = new File("d:\\java1223\\day18");

		String[] arr = dir.list(new FilenameFilter()
		{
			public boolean accept(File dir,String name)
			{

//				/System.out.println("dir:"+dir+"....name::"+name);
				/*
				if(name.endsWith(".bmp"))
					return true;
				else
				return false;
				*/
				return name.endsWith(".bmp");

			}
		});


		System.out.println("len:"+arr.length);
		for(String name : arr)
		{
			System.out.println(name);
		}
	}

	public static void listDemo()
	{
		File f = new File("c:\\abc.txt");

		String[] names = f.list();//调用list方法的file对象必须是封装了一个目录。该目录还必须存在。
		for(String name : names)
		{
			System.out.println(name);
		}
	}
	public static void listRootsDemo()
	{
		File[] files = File.listRoots();

		for(File f : files)
		{
			System.out.println(f);
		}
	}
}
第四:递归

函数自己调用自己,这种手法叫递归。

注意:

1:递归时一定要明确结束条件。避免死循环

2:注意递归次数,避免内存溢出。

应用场景:当某一功能要重复使用时。

举例1:

列出指定目录下文件或文件夹,包含子目录,即列出指定目录下所以内容

package day20;
import java.io.*;
public class FileDemo3 {
	public static void main(String[] args) {
		File dir=new File("d:\\java123\\myproject");
		System.out.println(dir.delete());
		showDir(dir,0);
		
	}
	public static String getLevel(int level)
	{
		StringBuilder sb=new StringBuilder();
		sb.append("|--");
		for(int x=0;x<level;x++)
		{
			sb.insert(0,"|  ");
		}
		return sb.toString();
		
		
	}
	public static void showDir(File dir,int level)
	{
		System.out.println(getLevel(level)+dir.getName());
		level++;
		File[] files=dir.listFiles();
		for(int x=0;x<files.length;x++)
		{
			if(files[x].isDirectory())
				showDir(files[x],level);
			else
				System.out.println(getLevel(level)+files[x]);
		}
		
	}
}
举例2:
删除一个带内容的目录。
删除原理:
在window中,删除目录从里面往外删除的。
既然是从里往外删除。就需要用到递归。
import java.io.*;
class  RemoveDir
{
	public static void main(String[] args) 
	{
		
		File dir = new File("d:\\testdir");
		removeDir(dir);
	}

	public static void removeDir(File dir)//删除文件夹所有内容 
	{
		File[] files = dir.listFiles();//将文件存入File数组
		
		for(int x=0; x<files.length; x++)
		{
			if(files[x].isDirectory())//是否是一个目录,不是目录调用自身
				removeDir(files[x]);
			else
				System.out.println(files[x].toString()+":-file-:"+files[x].delete());//打印删除目录
		}

		System.out.println(dir+"::dir::"+dir.delete());//打印删除文件夹
	}

}
举例3:
将一个指定目录下的java文件的绝对路径,存储到一个文本文件中。
建立一个java文件列表文件。

思路:
1,对指定的目录进行递归。
2,获取递归过程所以的java文件的路径。
3,将这些路径存储到集合中。
4,将集合中的数据写入到一个文件中。
import java.io.*;
import java.util.*;
class  JavaFileList
{
	public static void main(String[] args) throws IOException
	{
		
		File dir = new File("d:\\java1223");

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

		fileToList(dir,list);

		//System.out.println(list.size());


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

		


	}
	public static void fileToList(File dir,List<File> list)
	{
		File[] files = dir.listFiles();

		for(File file : files)
		{
			if(file.isDirectory())
				fileToList(file,list);
			else
			{
				if(file.getName().endsWith(".java"))
					list.add(file);
			}
		}
	}

	public static void writeToFile(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;
			}
		}
	}
}


  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值