黑马程序员——java基础-IO(二)

来源:互联网 发布:逆战血手队伤数据qq群 编辑:程序博客网 时间:2024/05/16 09:29

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

  第一节:File类
一、File类简述:
1、文件和目录路径名的抽象表示形式。
二、File类的特性:
1、可以将文件夹及文件封装成对象,对文件及文件夹的属性信息进行操作。
2、File对象可以作为差数传替给流的构造函数。
3、File.separator表示目录分割符,可以跨平台使用的。
三、File类的常用方法
1、构造方法
(1):File file = new File("e:\\demo\\a.txt");
(2):File file = new File("e:\\demo","a.txt");
(3):File file = new File("e:\\demo");
(4) File file2 = new File(file,"a.txt");
2、File类常用的功能
(1):创建
(1): boolean createNewFile();在指定位置创建文件,如果该文件已创建 侧返回false  。和输出流不一样当对象已建立文件就会存在  文件有可能被覆盖
(2):boolean mkdir();创建文件夹
(3):boolean mkdirs();创建多级文件夹
(2):删除
(2): boolean delete ();删除失败会返回false   如果文件正在被使用  删除不了 就返回false
(2): void deleteOnExit();在程序退出时删除指定的文件。
(3):判断
(1): boolean canExecute();文件是否可以执行;
(2): boolean exists()判断文件或目录是否存在;
(3): boolean isFile();是否是一个文件
(4): boolean isDirectory()是否是一个目录
(5): boolean isHidden()文件是否是一个隐藏的文件
(6): boolean isAbsolute()路径是否是一个绝对的路径
(4):获取
(1): String getName();获取文件的名字;
(2): String getPath();获取相对的路径;
(3): String getparent();获取父目录;该方法返回的是绝对路径中的父目录,如果获取的是相当路径则返回的是null,如果相对路径中有上一层目录那返回的则是上一层的目录。
(4): String getAbsolutePath();获取绝对路径;
(5): Long lastModified();获取最后修改文件的时间;
(6): Long length();获取文件的大小;
(5):列出文件及文件过滤
(1): static File[] listRoots();列出可用的文件系统根目录,即系统盘符
(2): String[] list();列出当前目录下所有文件,包括隐藏。调用list方法的file对象必须是封装了一个目录。该目录还必须存在。
(3): String[]list(FilenameFilter filter);返回一个字符串数组,获取目录中满足指定过滤器的文件或目录。
FilenameFilter:文件名过滤器,是一个接口,其中包含一个方法,accept(Filedir,String name),返回的是boolean型,对不符合条件的文件过滤掉。
(4): File[] listFiles();返回一个抽象路径名数组,获取当前文件夹下的所有文件和文件夹
(5): File[] ListFiles(FilenameFilter filter);返回抽象路径名数组,获取目录中满足指定过滤器的文件或目录。
(6):代码体现
小练习

练习一、

//1需求打印出某一个目录下所有的文件的文件名/*思路:源:是一个文件FileReader 需要高效BufferedReader  目的:控制台 假如目录中还有文件夹 就用递归的思想*/import java.io.*;class Demo7{public static void main(String[] args){//去关联一个文件File file=new File("d:\\javakan");getFile(file);}public static void getFile(File file){//判断关联的文件夹是否存在if (!file.exists()){System.out.println("文件夹为空");}//获取一个目录下的所有的文件及文件夹File[] fl=file.listFiles();for (File files:fl ){//判断是否是一个目录if (files.isDirectory()){//用递归getFile(files);}else{//打印文件的名字System.out.println(files.getName());}}}}
练习二、

//2需求打印出某一个目录下所有的文件的指定文件名字(目录里含目录)/*思路:1、创建一个File类对象并传入一个文件目录  2、判断目录是否存在  3、根据listFile方法获取File[]   4、利用for循环文件中要是还有目录的话用递归,否则就获取一个文件的文件名要是指定的话就输出*/import java.io.*;class Demo9{public static void main(String[] args){//去指定一个文件夹的路径File file=new File("d:\\kanjava");getFileName(file);}public static void getFileName(File file){//判断是否是一个文件夹if (!file.exists()){System.out.println("文件夹不存在");}File[] fil=file.listFiles();for (File fl:fil){//判断是否是一个目录if (fl.isDirectory()){//递归getFileName(fl);}else{//选择自己需要的文件类型if (fl.getName().endsWith(".txt")){//打印文件的名字System.out.println(fl.getName());}}}}}
练习三、

//3、把一个目录下的所有的文件复制到另一个路径下/*思路:1 创建两个File类对象一个是里面传入被复制目录另一是复制目录  2 判断被复制的目录是否存在 在判断复制目录是否存在不存在的话在进行创建,在判断是否是一个文件夹否则就在创建一个文件夹  3 根据listFiles方法得到File[]  4 在判断是否是一个文件夹是的话在调用自己的函数(递归)  5 要是不是一个目录就创建一个输出流而文件的名字就是被复制的文件名字  6 关闭流资源*/import java.io.*;class Demo10{public static void main(String[] args){//把要复制的文件夹和复制到哪的文件夹File oldFile=new File("d:\\javakan");File newFile=new File("copy");getCopy(oldFile,newFile);}public static void getCopy(File oldFile,File newFile){//判断源文件夹是否为空if (!oldFile.exists()){System.out.println("输入的文件夹不存在");}//要是复制的文件夹不存在就在创建一个if (!newFile.exists()){newFile.mkdir();}//如果不是一个目录在创建一个目录if (!newFile.isDirectory()){newFile.mkdir();}File[] file=oldFile.listFiles();for (File fl:file ){//判断是否是一个目录if (fl.isDirectory()){//复制好新文件夹的路径File fls=new File(newFile+"\\"+fl.getName());//递归getCopy(fl,fls);}else{//去关联一个文件BufferedReader br=null;//写到该文件中去BufferedWriter bw=null;try{br=new BufferedReader(new FileReader(fl));bw=new BufferedWriter(new FileWriter(newFile+"\\"+fl.getName()));String str=null;//循环读取while ((str=br.readLine())!=null){//进行写入,换行,刷新bw.write(str);bw.newLine();bw.flush();}}catch (IOException ioe){throw new RuntimeException("出现异常");}finally{try{//关闭资源br.close();bw.close();}catch (IOException io){throw new RuntimeException("异常");}}}}}}
练习四、

//4、删除一个目录下所有的文件(文件中包含目录)/*思路:1、创建一个File类对象并指定好要删除的目录2、判断是否是一个目录3、调用listFiles方法4、高级for循环 进行对File类遍历5、判断是否是一个目录是的话就在调用自己的函数(递归)6 不是目录就是文件了 进行删除*/import java.io.*;class Demo11{public static void main(String[] args){File file =new File("copy");deleteFile(file);}public static void deleteFile(File file){if (!file.exists()){System.out.println("文件为空");}File[] files=file.listFiles();for (File fl:files ){if (fl.isDirectory()){deleteFile(fl);fl.delete();}else{fl.delete();}}}}
三、递归
1、何为递归?
函数自身直接或者间接的调用到了自身,一个功能在被重复使用,并每次使用时,参与运算的结果和上一次调用有关,称之为递归。 
2、递归的注意事项:
(1):要有出口,否则就是死递归
(2):次数不能过多,否则内存溢出
(3):构造方法不能递归使用
4、代码体现

//题目:利用递归方法求5!。class Demo23{public static void main(String[] args){//调用函数,并返回一个值int in=getSum(5);//打印该值System.out.println(in);}public static int getSum(int s){//定义一个变量int temp=1;if (s==1){temp=1;}else{//进行递归temp=s*getSum(s-1);}return temp;}}
第二节:properties类
一、properties类的由来
   1、是一个集合类,Hashtable的子类,属性列表中每个键及其对应值都是一个字符串,无泛型,是集合与io相结合的类。
二、Personties类的特有功能
1、public Object setProperty(String key,String value)
2、public String getProperty(String key)
3、public Set<String> stringPropertyNames()
三、它和IO流结合的方法
1、把键值对形式的文本文件内容加载到集合中
(1)public void load(Reader reader)
(2)public void load(InputStream inStream)
2、把集合中的数据存储到文本文件中
(1)public void store(Writer writer,String comments)
(2)public void store(OutputStream out,String comments)
   3、案例:
(1):根据给定的文件判断是否有键为"lisi"的,如果有就修改其值为100

//1根据给定的文件判断是否有键为"lisi"的,如果有就值修改其值为100/*思路: 1、创建一个File类并把指定的文件传入   2、源:是一个文件FileReader去关联一个文件   3、创建Perparties对象   4、用load方法把io流传入到集合当中去   5、在用集合的相关方法进行对集合遍历   6、如果遇到了lisi就修改为100   7、在吧集合转换成一个文件。   8、关闭资源*/import java.io.*;import java.util.*;class Demo12{public static void main(String[] args)throws IOException{//创建一个File类并把指定的文件传入File file=new File("4.txt");getFile(file);}public static void getFile(File file)throws IOException{//创建Perparties对象Properties pp=new Properties();//FileReader去关联一个文件FileReader fr=new FileReader(file);pp.load(fr);Set<String>set=pp.stringPropertyNames();//在用集合的相关方法进行对集合遍历for (String key:set ){//如果遇到了lisi就修改为100if (key.equals("lisi")){pp.setProperty(key,"100");break;}}//创建FileWriter类的对象FileWriter fw=new FileWriter(file);//把集合转换成一个文件pp.store(fw,null);//关闭资源fr.close();fw.close();}}
(2):写一个程序实现控制猜数字小游戏程序不能玩超过5次
//(2):写一个程序实现控制猜数字小游戏程序不能玩超过5次/*思路:1、创建一个File类对象传入一个文件用于记录玩的次数2、创建Properties类的对象3、在创建一个读取流FileReader对象并关联一个文件4、把io流加载到集合当中去5、定义一个计数器运行一次就往集合当中添加一次6、在根据集合转变成文件7、当在次运行就会判断文件中的次数要是到了次数就报出异常你已经到次数了8、关闭资源*/import java.io.*;import java.util.*;class Demo13{public static void main(String[] args)throws IOException{//创建File类对象并传入一个文件File file=new File("count.txt");//把file类的对象传入到函数当中去int count=getFile(file);//判断次数是否到达if (count>5){System.out.println("次数已到");}else{System.out.println("游戏开始");}}public static int getFile(File file)throws IOException{int count=1;//判断文件是否为空if (!file.exists()){file.createNewFile();}//创建Properties类的对象Properties pp=new Properties();//去关联一个文件FileReader fr=new FileReader(file);//把文件转换成一个集合pp.load(fr);//关闭资源fr.close();String value=pp.getProperty("time");//判断使用次数if (value==null){System.out.println("hehe开始了");pp.setProperty("time","1");}else{count=Integer.parseInt(value);count++;pp.setProperty("time",count+"");System.out.println(count+"开始了");}FileWriter fw=new FileWriter(file);//把集合转换成一个文件pp.store(fw,null);//关闭资源fw.close();//返回一个数值return count;}}
第三节:打印流
一、简述:
1、字节打印流 PrintStream  字符打印流 PrintWriter
2、该流提供了打印方法,可以将各种数据类型的数据都原样打印
3、特点:
1、只操作目的地,不操作数据源
2、可以操作任意类型的数据
3、如果启用了自动刷新,在调用println()方法的时候,能够换行并刷新
4、可以直接操作文件
问题:哪些流可以直接操作文件呢?
看API,如果其构造方法能够同时接收File和String类型的参数,一般都是可以直接操作文件的
4、复制文本文件
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
PrintWriter pw = new PrintWriter(new FileWriter("b.txt"),true);
String line = null;
while((line=br.readLine())!=null) {
pw.println(line);
}
pw.close();
br.close();
二、打印流构造函数可以接收的参数类型
1、字节打印流:PrintStream 构造函数可以接收的参数类型:
(1) file对象, File
(2) 字符串路径  String
(3) 字节输出流 OutputStream
2、字符打印流:PrintWriter 构造函数可以接收的参数类型
(1) file对象。 File
(2) 字符串路径  String
(3) 字节输出流 OutputStream
(4) 字符输出流 Writer
3、代码体现
import java.io.*;class IoDemo4{public static void main (String[] args)throws Exception{//从键盘上读取数据BufferedReader bur = new BufferedReader (new InputStreamReader (System.in));//显示在控制台上  PrintWriter pw = new PrintWriter(System.out,true);//true 是自动刷新不用flsh()方法了。  String line = null ;  //循环进行读取  while ((line=bur.readLine())!=null)  {  //指定键盘录入结束的标记  if ("over".equals(line))break;  //把接收到的数据转换成大写  pw.println(line.toUpperCase()); // pw.flush();  }  //关闭资源   pw.close();bur.close();}}
 第四节:合并流
一、SequenceInputStream概述
1、SequenceInputStream类可以将多个输入流串流在一起,合并为一个输入流,因此,该流也被称为合并流。
2、把多个文件的内容写入到一个文本文件
        3、SequenceInputStream的构造方法
(1) SequenceInputStream(InputStream s1, InputStream s2)  
(2) SequenceInputStream(Enumeration<? extends InputStream> e)

4、代码体现

//需求1 对多个流进行合并(也就是把几个文件合成一个文件) import java.util.*;import java.io.*;class IoDemo4{public static void main (String[] args)throws Exception{//创建Vector类的对象Vector<FileInputStream>  v = new Vector<FileInputStream>();//添加读取流的对象v.add(new FileInputStream("d:\\1.txt"));v.add(new FileInputStream("d:\\2.txt"));v.add(new FileInputStream("d:\\3.txt"));Enumeration<FileInputStream> en =v.elements();//把文件进行合并SequenceInputStream sis = new SequenceInputStream (en);//创建FileOutputStream类的对象,写入到目的中FileOutputStream fos =new FileOutputStream("4.txt");byte[] buf = new byte[1024];int len =0;//循环读取while ((len=sis.read(buf))!=-1){//写入数据fos.write(buf,0,len);}//关闭资源sis.close();fos.close();}}

第五节:序列化流
一、简述:
1、序列化流 ObjectOutputStream 反序列化流 ObjectInputStream
2、序列化操作问题
(1)为什么要实现序列化?
原因就是把对象进行持久化,对象本来是存储在堆内存中的,当程序结束的时候,对象在堆内存中被回收了,为了方便下次或其他人用,所以把对象进行了序列化
(2)序列化数据后,再次修改类文件,读取数据会出问题,如何解决呢?
使用transient关键字声明不需要序列化的成员变量,也可以在类文件中,给出一个固定的序列化id值。
(3)如何实现序列化呢?
让被序列化的对象所属类实现序列化接口,该接口是一个标记接口。没有功能需要实现。
第六节:管道流
一、简述:
1、管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。
2、管道输入流 PipedOutputStream  管道输出流 PipedInputStream 
3、输入输出可以直接进行连接,通过结合线程使用。线程与io结合的类。
4、代码的体现

import java.io.*;class IoDemo4{public static void main (String[] args)throws Exception{//创建读取流和写入流的对象PipedInputStream  in  = new PipedInputStream();PipedOutputStream out  = new PipedOutputStream();//把读和写接上in.connect(out);//创建读和写的对象Read r = new Read(in);Write w = new Write(out);//创建线程并调用new Thread(r).start();new Thread(w).start();}}//自定义一个读取类实现Runnable接口class Read implements Runnable{private PipedInputStream in;Read (PipedInputStream  in){this.in = in;}//覆盖run方法public void run (){try{//自定义一个数组byte[] buf = new byte[1024];//进行读取int len = in.read(buf);String  s  = new String(buf,0,len);//打印读取的内容System.out.println(s);//关闭资源in.close();}catch (Exception  e){throw new RuntimeException("管道流读写失败");}}}//自定义一个写入类实现Runnable接口class Write implements Runnable {private PipedOutputStream out;Write (PipedOutputStream  out){this.out = out;}//覆盖run方法public void run (){try{//把数据写入到管道中out.write("xiao jia huo haha ha ha ".getBytes());//关闭资源out.close();}catch (Exception e ){throw new RuntimeException("管道流写入失败");}}}
第七节:随机访问流--RandomAccessFile类
一、简述:
1、该类不是算是IO体系中子类,而是直接继承自object
2、该类是io包中成员 因为他具备读和写的功能,内部封装了一个数组,而且通过指针对数组元素进行操作,可以通过 getFilePointer获取指针的位置,同时可以通过seek改变指针的位置。
3、该类其实完成读写的原理就是内部封装了字节输入流和输出流。
4、通过构造函数可以看出,该类只能操作文件,而且操作文件还有模式:只读 r,,,,读写 rw,,,,等
  如果模式为r 不会创建文件,会去读取一个已存在文件,如果该文件不存在,则会出现异常,如果模式rw 操作的文件不存在,会自动创建,如果存在则不会覆盖。
      而且该对象的构造函数要操作的文件不存在就会自动创建,如果存在则不会覆盖。
第八节:用于操作字节数组的流对象
一、简述:
1、ByteArrayInputStream 在构造的时候,需要接受数据源,,而且数据源是一个字节数组。
2、ByteArrayOutputStream 在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组,这就是数据目的地
注:因为这两个流对象都是操作数组,并,没有使用系统资源。所以不用进行close关闭。也不必抛IO异常。
二、流的操作规律;
源设备:
键盘  System.in  硬盘  FileStream  内存  ArrayStream
目的设备:
控制台  System.out  硬盘  FileStream  内存  ArrayStream
三、需要了解的
1、字符数组 CharArrayReader 与  CharArrayWriter 
2、字符串  StringReader  与  StringWriter 

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

0 0
原创粉丝点击