A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始




8、IO

8.2 IO流

    8.2.7 File类

    需求:获取c盘目录下的隐藏文件。

    代码:
  1. import java.io.File;
  2. import java.io.FilenameFilter;

  3. public class FileListDemo{
  4.        public static void main(String[] args){
  5.             listDemo();
  6.       }

  7.        public static void listDemo(){
  8.             File dir = new File("c:\\" );

  9.             File[] files = dir.listFiles( new FilterByHidden());

  10.              for(File file : files){
  11.                   System.out.println(file);
  12.             }
  13.       }
  14. }

  15. class FilterByHidden implements FilenameFilter{
  16.        public boolean accept(File dir,String name){
  17.              return dir.isHidden();
  18.       }
  19. }
复制代码
   运行结果:

    8.2.8 递归  


    函数自身直接或者间接的调用到了自身。
    一个功能在被重复使用,并每次使用时,参与运算的结果和上一次调用有关。这时可以用递归来解决问题。


    P.S.
    1、递归一定明确条件,否则容易栈溢出。
    2、注意一下递归的次数。

    需求:对指定目录进行所有内容的列出(包含子目录中的内容),也可以理解为深度遍历。

    代码:
  1. import java.io.File;

  2. public class FileListDemo{
  3.        public static void main(String[] args){
  4.             File dir = new File("D:\\Java\\jdk1.6.0_02\\include" );
  5.             listAll(dir,0);
  6.       }

  7.        public static void listAll(File dir, int level){
  8.             System.out.println(getSpace(level) + "dir:" + dir.getAbsolutePath());
  9.              //获取指定目录下当前的所有文件夹或者文件对象
  10.             level++;
  11.             File[] files = dir.listFiles();

  12.              for (int x = 0; x < files.length; x++){
  13.                    if (files[x].isDirectory()){
  14.                         listAll(files[x],level);
  15.                   }
  16.                   System.out.println(getSpace(level) + "file:" + files[x].getAbsolutePath());
  17.             }
  18.       }

  19.        private static String getSpace( int level){
  20.             StringBuilder sb = new StringBuilder();

  21.             sb.append( "|--" );
  22.              for (int x = 0; x < level; x++){
  23.                   sb.append( "| " );
  24.             }

  25.              return sb.toString();
  26.       }
  27. }
复制代码
    运行结果:

    需求:利用递归求6的二进制值。

    代码:
  1. public class DiGuiDemo{
  2.        public static void main(String[] args){
  3.             toBin(6);
  4.       }

  5.        public static void toBin(int num){
  6.              if(num > 0){
  7.                   toBin(num/2);
  8.                   System.out.print(num%2);
  9.             }
  10.       }
  11. }
复制代码
   运行结果:

    需求:利用递归求1到10的和。

    代码:
  1. public class DiGuiDemo{
  2.        public static void main(String[] args){
  3.              int sum = getSum(10);
  4.             System.out.println(sum);
  5.       }

  6.        public static int getSum(int num){
  7.              if(num == 1)
  8.                    return 1;
  9.              return num + getSum(num - 1);
  10.       }
  11. }
复制代码
   运行结果:



    需求:删除一个带内容的目录。
    原理:必须从里面往外删,需要进行深度遍历。


    代码:
  1. import java.io.File;

  2. public class RemoveDirTest{
  3.        public static void main(String[] args){
  4.             File dir = new File("d:\\demo" );
  5.             removeDir(dir);
  6.       }

  7.        public static void removeDir(File dir){
  8.             File[] files = dir.listFiles();

  9.              for(File file : files){
  10.                    if(file.isDirectory()){
  11.                         removeDir(file);
  12.                   } else{
  13.                         System.out.println(file + ":" + file.delete());
  14.                   }
  15.             }
  16.             System.out.println(dir + ":" + dir.delete());
  17.       }
  18. }
复制代码
   运行结果:

    8.2.9 Properties集合


    Map
          |--Hashtable
               |--Properties


    特点:
    1. 该集合中的键和值都是字符串类型。
    2. 集合中的数据可以保存到流中,或者从流中获取。

    3. 通常该集合用于操作以键值对形式存在的配置文件。

    Properties集合的存和取。

    示例1:
  1. import java.util.Properties;
  2. import java.util.Set;

  3. public class PropertiesDemo{
  4.        public static void main(String[] args){
  5.             propertiesDemo();
  6.       }

  7.        public static void propertiesDemo(){
  8.              //创建一个Properties集合
  9.             Properties prop = new Properties();

  10.              //存储元素
  11.             prop.setProperty( "zhangsan","10" );
  12.             prop.setProperty( "lisi","20" );
  13.             prop.setProperty( "wangwu","30" );
  14.             prop.setProperty( "zhaoliu","40" );
  15.             
  16.              //修改元素
  17.             prop.setProperty( "wangwu","26" );

  18.              //取出所有元素
  19.             Set<String> names = prop.stringPropertyNames();

  20.              for(String name : names){
  21.                   String value = prop.getProperty(name);
  22.                   System.out.println(name + ":" + value);
  23.             }
  24.       }
  25. }
复制代码
   运行结果:

    演示Properties集合和流对象相结合的功能。

    示例2:
  1. import java.util.Properties;

  2. public class PropertiesDemo{
  3.        public static void main(String[] args){
  4.             propertiesDemo();
  5.       }

  6.        public static void propertiesDemo(){
  7.             Properties prop = new Properties();

  8.             prop.setProperty( "zhangsan","10" );
  9.             prop.setProperty( "lisi","20" );
  10.             prop.setProperty( "wangwu","30" );
  11.             prop.setProperty( "zhaoliu","40" );
  12.             
  13.             prop.list(System.out);
  14.       }
  15. }
复制代码
    运行结果:

    示例3:  
  1. import java.io.FileOutputStream;
  2. import java.util.Properties;

  3. public class PropertiesDemo{
  4.        public static void main(String[] args) throws Exception  {
  5.             propertiesDemo();
  6.       }

  7.        public static void propertiesDemo() throws Exception {
  8.             Properties prop = new Properties();

  9.             prop.setProperty( "zhangsan","10" );
  10.             prop.setProperty( "lisi","20" );
  11.             prop.setProperty( "wangwu","30" );
  12.             prop.setProperty( "zhaoliu","40" );
  13.             
  14.              //想要将这些集合中的字符串键值信息持久化存储到文件中
  15.              //需要关联输出流
  16.             FileOutputStream fos = new FileOutputStream("info.txt" );

  17.              //将集合中数据存储到文件中
  18.             prop.store(fos, "name+age");

  19.             fos.close();
  20.       }
  21. }
复制代码
    运行结果:





    示例4:
  1. import java.io.BufferedReader;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileReader;
  5. import java.io.FileWriter;
  6. import java.io.IOException;
  7. import java.util.Properties;

  8. public class PropertiesDemo{
  9.        public static void main(String[] args) throws Exception {
  10.             propertiesDemo();
  11.       }

  12.        public static void propertiesDemo() throws Exception {
  13.             Properties prop = new Properties();

  14.              //集合中的数据来自于一个文件。
  15.              //注意:必须要保证该文件中的数据是键值对。
  16.              //需要使用到读取流
  17.             FileInputStream fis = new FileInputStream("info.txt" );

  18.              //使用load方法
  19.             prop.load(fis);
  20.             prop.list(System.out);

  21.             test();
  22.             myLoad();
  23.       }
  24.       
  25.        //对已有的配置文件中的信息进行修改。
  26.        //读取这个文件。并将这个文件中的键值数据存储到集合中。再通过集合对数据进行修改。
  27.        //再通过流将修改后的数据存储到文件中
  28.        public static void test() throws Exception {
  29.              //读取这个文件
  30.             File file = new File("info.txt" );
  31.              if(!file.exists()){
  32.                   file.createNewFile();   
  33.             }
  34.             FileReader fr = new FileReader("info.txt" );

  35.              //创建集合存储配置信息
  36.             Properties prop = new Properties();

  37.              //将流中信息存储到集合中
  38.             prop.load(fr);

  39.             prop.setProperty( "wangwu","26" );

  40.             FileWriter fw = new FileWriter(file);

  41.             prop.store(fw, "");

  42.             fr.close();
  43.       }

  44.        //模拟一下load方法
  45.        public static void myLoad() throws Exception {
  46.             Properties prop = new Properties();

  47.             BufferedReader bufr = new BufferedReader(new FileReader("info.txt" ));
  48.       
  49.             String line = null;

  50.              while((line = bufr.readLine()) != null){
  51.                    if(line.startsWith("#" ))
  52.                          continue;
  53.                   String[] arr = line.split( "=");
  54.                   prop.setProperty(arr[0],arr[1]);
  55.             }

  56.             prop.list(System.out);
  57.             bufr.close();
  58.       }
  59. }
复制代码
  运行结果:

    需求:获取一个应用程序运行的次数,如果超过5次,给出使用次数已到请注册的提示,并不要再运行程序。

    思路:
    1、应该有计数器
    每次程序启动都需要计数一次,并且是在原有的次数上进行计数。
    2、计数器就是一个变量。突然冒出一想法,程序启动时进行计数,计数器必须存在于内存并进行运算。
    可是程序一结束,计数器消失了。那么再次启动该程序,计数器又重新被初始化了。
    而我们需要多次启动同一个应用程序,使用的是同一个计数器。
    这就需要计数器的生命周期边长,从内存存储到硬盘文件中。
    3、如何使用这个计数器呢?
    首先,程序启动时,应该先读取这个用于记录计数器信息的配置文件。
    获取上一次计数器次数。并进行使用次数的判断。
    其次,对该次数进行自增,并自增后的次数重新存储到配置文件中。
    4、文件中的信息该如何进行存储并体现。
    直接存储次数值可以,但是不明确该数据的含义。所以起名字就变得很重要。
    这就有了名字和值的对应,所以可以使用键值对。
    可是映射关系map集合搞定,又需要读取硬盘上的数据,所以map+io=properties。


    代码:
  1. import java.io.File;
  2. import java.io.FileInputStream;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5. import java.util.Properties;

  6. public class PropertiesTest{
  7.        public static void main(String[] args) throws IOException{
  8.             getAppCount();
  9.       }

  10.        public static void getAppCount() throws IOException {
  11.              //将配置文件封装成File对象
  12.             File confile = new File("count.properties" );

  13.              if(!confile.exists()){
  14.                   confile.createNewFile();
  15.             }

  16.             FileInputStream fis = new FileInputStream(confile);
  17.       
  18.             Properties prop = new Properties();

  19.             prop.load(fis);

  20.              //从集合中通过键获取次数
  21.             String value = prop.getProperty( "time");
  22.             
  23.              //定义计数器,记录获取到的次数
  24.              int count = 0;
  25.              if(value != null){
  26.                   count = Integer.parseInt(value);
  27.                    if(count >= 5){
  28.                          throw new RuntimeException("使用次数已到,请注册,给钱!" );
  29.                   }
  30.             }
  31.             count++;

  32.              //将改变后的次数重新存储到集合中。
  33.             prop.setProperty( "time",count + "" );

  34.             FileOutputStream fos = new FileOutputStream(confile);

  35.             prop.store(fos, "");

  36.             fos.close();
  37.             fis.close();
  38.       }
  39. }
复制代码
   运行结果:

    需求:获取指定目录下,指定扩展名的文件(包含子目录中的),并且将这些文件的绝对路径写入到一个文本文件中。
    简单说:就是建立一个指定扩展名的文件的列表。

    思路:
    1. 必须进行深度遍历。
    2. 要在遍历的过程中进行过滤,将符合条件的内容都存储到容器中。
    3. 对容器中的内容进行遍历并将绝对路径写入到文件中。


    代码:
  1. import java.io.BufferedWriter;
  2. import java.io.File;
  3. import java.io.FileWriter;
  4. import java.io.FilenameFilter;
  5. import java.io.IOException;
  6. import java.util.ArrayList;
  7. import java.util.List;

  8. public class Test{
  9.        public static void main(String[] args) throws IOException {
  10.             File dir = new File("d:\\code" );
  11.             FilenameFilter filter = new FilenameFilter(){
  12.                    public boolean accept(File dir,String name){
  13.                          return name.endsWith(".java" );
  14.                   }
  15.             };

  16.             List<File> list = new ArrayList<File>();
  17.             getFiles(dir,filter,list);
  18.             File destFile = new File(dir,"javalist.txt" );
  19.             write2File(list,destFile);
  20.       }
  21.        /*
  22.       对指定目录中的内容进行深度遍历,并按照指定过滤器,进行过滤。
  23.       将过滤后的内容存储到指定容器List中。
  24.       */
  25.        public static void getFiles(File dir,FilenameFilter filter,List<File> list){
  26.             File[] files = dir.listFiles();
  27.             
  28.              for(File file : files){
  29.                    //递归
  30.                    if(file.isDirectory()){
  31.                         getFiles(file,filter,list);
  32.                   } else{
  33.                          //对便利到的文件进行过滤器的过滤。将符合条件File对象,存储到List集合中
  34.                          if(filter.accept(dir,file.getName())){
  35.                               list.add(file);
  36.                         }
  37.                   }
  38.             }
  39.       }

  40.        public static void write2File(List<File> list,File destFile) throws IOException{
  41.             BufferedWriter bufw = null;
  42.              try{
  43.                   bufw = new BufferedWriter(new FileWriter(destFile));
  44.                   
  45.                    for(File file : list){
  46.                         bufw.write(file.getAbsolutePath());
  47.                         bufw.newLine();
  48.                         bufw.flush();
  49.                   }
  50.             } finally{
  51.                    if(bufw!=null)
  52.                          try{
  53.                               bufw.close();
  54.                         } catch(IOException e){
  55.                                throw new RuntimeException("关闭失败");
  56.                         }
  57.             }
  58.       }
  59. }
复制代码
    运行结果:



    8.2.10 IO包中的其他类

    打印流

    PrintWriter与PrintStream:可以直接操作输入流和文件。


    PrintStream为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
    与其他输出流不同,PrintStream永远不会抛出IOException。
    PrintStream打印的所有字符都使用平台的默认字符编码转换为字节。

    在需要写入字符而不是写入字节的情况下,应该使用PrintWriter类。

    PrintStream:
    1. 提供了打印方法可以对多种数据类型值进行打印,并保持数据的表示形式
    2. 它不抛IOException

    构造函数,接收三种类型的值:
    1. 字符串路径
    2. File对象
    3. 字节输出流


    示例1:
  1. import java.io.PrintStream;

  2. public class PrintStreamDemo{
  3.        public static void main(String[] args) throws Exception {
  4.             PrintStream out = new PrintStream("print.txt" );
  5.             
  6.              //write(int b)方法只写最低8位
  7.             out.write(97); //a
  8.             //print方法将97先变成字符串保持原样将数据打印到目的地
  9.             out.print(97); //97

  10.             out.close();
  11.       }
  12. }
复制代码
   运行结果:



    PrintWriter:字符打印流

    构造函数参数:
    1. 字符串路径
    2. File对象
    3. 字节输出流
    4. 字符输出流


    示例2:
  1. import java.io.BufferedReader;
  2. import java.io.InputStreamReader;
  3. import java.io.PrintWriter;
  4. import java.io.IOException;

  5. public class PrintWriterDemo{
  6.        public static void main(String[] args) throws IOException {
  7.             BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
  8.             PrintWriter out = new PrintWriter(System.out);

  9.             String line = null;
  10.              while((line = bufr.readLine()) != null){
  11.                    if("over" .equals(line))
  12.                          break;
  13.                   out.println(line.toUpperCase());
  14.                   out.flush();
  15.             }

  16.             out.close();
  17.             bufr.close();
  18.       }
  19. }
复制代码
    运行结果:

    示例3:  
  1. import java.io.BufferedReader;
  2. import java.io.FileWriter;
  3. import java.io.InputStreamReader;
  4. import java.io.PrintWriter;
  5. import java.io.IOException;

  6. //写入到out.txt文件中
  7. public class PrintWriterDemo{
  8.        public static void main(String[] args) throws IOException {
  9.             BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
  10.              //PrintWriter构造函数的第二个参数设置为true,表示自动刷新
  11.             PrintWriter out = new PrintWriter(new FileWriter("out.txt" ),true);

  12.             String line = null;
  13.              while((line = bufr.readLine()) != null){
  14.                    if("over" .equals(line))
  15.                          break;
  16.                   out.println(line.toUpperCase());
  17.             }

  18.             out.close();
  19.             bufr.close();
  20.       }
  21. }
复制代码
    运行结果:




    序列流
    SequenceInputStream:对多个流进行合并。

    需求:将1.txt、2.txt、3、txt文件中的数据合并到一个文件中。

    代码:
  1. import java.io.FileInputStream;
  2. import java.io.FileOutputStream;
  3. import java.io.SequenceInputStream;
  4. import java.util.Enumeration;
  5. import java.util.Vector;

  6. public class SequenceInputStreamDemo{
  7.        public static void main(String[] args) throws Exception {
  8.             Vector<FileInputStream> v = new Vector<FileInputStream>();

  9.             v.add( new FileInputStream("1.txt" ));
  10.             v.add( new FileInputStream("2.txt" ));
  11.             v.add( new FileInputStream("3.txt" ));      

  12.             Enumeration<FileInputStream> en = v.elements();

  13.             SequenceInputStream sis = new SequenceInputStream(en);

  14.             FileOutputStream fos = new FileOutputStream("4.txt" );

  15.              byte[] buf = new byte[1024];
  16.             
  17.              int len = 0;

  18.              while((len = sis.read(buf)) != -1){
  19.                   fos.write(buf,0,len);   
  20.             }

  21.             fos.close();
  22.             sis.close();
  23.       }
  24. }
复制代码
   运行结果:














    使用ArrayList比Vector效率更高。

    改进后代码:
  1. import java.io.FileInputStream;
  2. import java.io.FileOutputStream;
  3. import java.io.SequenceInputStream;
  4. import java.util.ArrayList;
  5. import java.util.Collections;
  6. import java.util.Enumeration;
  7. import java.util.Iterator;

  8. public class SequenceInputStreamDemo{
  9.        public static void main(String[] args) throws Exception {

  10.             ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
  11.              for(int x = 1; x <= 3; x++){
  12.                   al.add( new FileInputStream(x + ".txt" ));
  13.             }
  14.             
  15.              final Iterator<FileInputStream> it = al.iterator();
  16.             
  17.             Enumeration<FileInputStream> en = Collections.enumeration(al);

  18.              /*
  19.             //Collections工具类的enumeration方法核心代码:
  20.             Enumeration<FileInputStream> en = new Enumeration<FileInputStream>(){
  21.                   public boolean hasMoreElements(){
  22.                         return it.hasMoreElements();
  23.                   }

  24.                   public FileInputStream nextElement(){
  25.                         return it.next();
  26.                   }
  27.             };*/

  28.             SequenceInputStream sis = new SequenceInputStream(en);

  29.             FileOutputStream fos = new FileOutputStream("4.txt" );

  30.              byte[] buf = new byte[1024];
  31.             
  32.              int len = 0;

  33.              while((len = sis.read(buf)) != -1){
  34.                   fos.write(buf,0,len);   
  35.             }

  36.             fos.close();
  37.             sis.close();
  38.       }
  39. }
复制代码

~END~




22 个回复

倒序浏览
阳哥笔记好全面啊.必须转走
回复 使用道具 举报
更新速度挺快的,赞一个
回复 使用道具 举报
阳哥,神速,根本停不下啦
回复 使用道具 举报
阳哥,很好!很强大!
回复 使用道具 举报
阳哥真的好厉害哈,继续加油了哈
回复 使用道具 举报
赞!赞!赞!赞!赞!赞!
回复 使用道具 举报
New_PS 中级黑马 2015-6-11 23:04:36
8#
学习ing学习ing
回复 使用道具 举报

阳哥,神速,根本停不下啦
回复 使用道具 举报
赞一个。。。
回复 使用道具 举报
正在学IO,刚好来看看
回复 使用道具 举报
更新速度挺快的,赞一个
回复 使用道具 举报
分享快乐 赞一个
回复 使用道具 举报
阳哥笔记超赞哦 !!
回复 使用道具 举报
又来顶帖子了!赞一个!!!!!!!!!!!!!!!!!!!!!!!!!!
回复 使用道具 举报
不错   顶!!!!!!!!!!!!!!!!!!!!!!!!!!!
回复 使用道具 举报
不错呀!真心不过呀!
回复 使用道具 举报
不错 、顶!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
回复 使用道具 举报
我能和阳哥交个朋友吗?
回复 使用道具 举报
最近正在学,好赞。。
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马