Java基础日记———IO流(下)

原创 2015年07月09日 11:18:02
一.概述
   1.File:
    用来将文件或者文件夹封装成对象。
    方便对文件与文件夹的属性信息进行操作。
    File对象可以作为参数传递给流的构造函数
    它是文件和目录路径名的抽象表示形式。
    用户界面和操作系统使用与系统相关的路径名字符串 来命名文件和目录。此类呈现分层路径名的一个抽象的、与系统无关的视图。
   2.Properties
    Properties是hashtable的子类。
    也就是说它具备map集合的特点。而且它里面存储的键值对都是字符串。
    是集合中和IO技术相结合的集合容器。
    该对象的特点:可以用于键值对形式的配置文件。
    那么在加载数据时,需要数据有固定格式:键=值。
    3.其他流对象
   (1)打印流
     该流提供了打印方法,可以将各种数据类型的数据都原样打印。
     字节打印流:  PrintStream ,构造函数可以接收的参数类型: 
        ①file对象。File
        ②字符串路径。String
        ③字节输出流。OutputStream
     字符打印流:PrintWriter,构造函数可以接收的参数类型: 
        ①file对象。File
        ②字符串路径。String
        ③字节输出流。OutputStream
        ④字符输出流,Writer。
    (2)序列流
          SequenceInputStream 表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。
      SequenceInputStream(InputStream s1, InputStream s2)
      通过记住这两个参数来初始化新创建的 SequenceInputStream(将按顺序读取这两个参数,先读取 s1,然后读取 s2),以提供从此 SequenceInputStream 读取的字节。    
二.详细信息
1.File类常见方法:
(1)创建。
     boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。
      和输出流不一样,输出流对象一建立创建文件。而且文件已经存在,会覆盖。
    boolean mkdir():创建文件夹。
    boolean mkdirs():创建多级文件夹。
(2)删除。
     boolean delete():删除失败返回false。如果文件正在被使用,则删除不了返回falsel。
     void deleteOnExit();在程序退出时删除指定文件。
(3)判断。
     boolean exists() :文件是否存在.
     isFile(): 测试此抽象路径名表示的文件是否是一个标准文件。
     isDirectory():测试此抽象路径名表示的文件是否是一个目录。
     isHidden():测试此抽象路径名指定的文件是否是一个隐藏文件
     isAbsolute():测试此抽象路径名是否为绝对路径名。
(4)获取信息。
     getName():
     getPath():
     getParent(): 返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。
     getAbsolutePath() : 返回此抽象路径名的绝对路径名字符串。
     long lastModified() : 返回此抽象路径名表示的文件最后一次被修改的时间。
     long length(): 返回由此抽象路径名表示的文件的长度。
2.File对象功能:文件列表
    ①list() :返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录 
    注意:调用list方法的file对象必须是封装了一个目录。该目录还必须存在
    ②list(FilenameFilter filter):返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。

代码示例:

      File dir = new File("d:\\java1223\\day18");
         String[] arr = dir.list(new FilenameFilter()
          {
               public boolean accept(File dir,String name)
               {
                    return name.endsWith(".bmp");
                } 
          });
          System.out.println("len:"+arr.length);
          for(String name : arr)
          {
                  System.out.println(name);
          }
③列举出指定文件或者文件包含子目录中的内容。
    因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可。
    在列出过程中出现的还是目录的话,还可以再次调用本功能。
    也就是函数自身调用自身。
    这种表现形式,或者编程手法,称为递归。
递归要注意:
   限定条件。
   要注意递归的次数。尽量避免内存溢出。

代码示例:

    public class FileTest {
     public static void main(String[] args) {
             File dir = new File("e:\\demodir");
             listAll(dir,0);
         }
      public static void listAll(File dir,int level) {
             System.out.println(getSpace(level)+dir.getName());
             //获取指定目录下当前的所有文件夹或者文件对象
              level++;  
             File[] files = dir.listFiles();
             for(int x=0; x<files.length; x++){
                 if(files[x].isDirectory()){
                     listAll(files[x],level);
                 }
                 else
                 System.out.println(getSpace(level)+files[x].getName());
           }
     }

   private static String getSpace(int level) { //该方法是目录带层次。
             StringBuilder sb = new StringBuilder();
             sb.append("|--");
            for(int x=0; x<level; x++){
                     sb.insert(0,"| ");
             }
             return sb.toString();
         }
    }
 需求二:删除一个带内容的目录。  
 原理:必须从最里面往外删。
 需要进行深度遍历。

代码示例:

    public static void removeDir(File dir) {
    File[] files = dir.listFiles();
     for(File file : files){
         if(file.isDirectory()){
         removeDir(file);
         }else{
             System.out.println(file+":"+file.delete());
          }
     }  
             System.out.println(dir+":"+dir.delete());
  }
3.Properties的应用
方法摘要:
stringPropertyNames():返回此属性列表中的键集,其中该键及其对应值是字符串,如果在主属性列表中未找到同名的键,则还包括默认属性列表中不同的键。
    setProperty(String key, String value):调用 Hashtable 的方法 put。
    load(InputStream inStream): 从输入流中读取属性列表(键和元素对)。
例子:如何将流中的数据存储到集合中? 
       想要将info.txt中键值数据存到集合中进行操作。
      (1)用一个流和info.txt文件关联。
      (2)读取一行数据,将该行数据用"="进行切割。
      (3)等号左边作为键,右边作为值。存入到Properties集合中即可。
其实也就是load()方法的原理。

代码示例:

  public static void method_1()throws IOException
     {
          BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));
          String line = null; 
          Properties prop = new Properties();
          while((line=bufr.readLine())!=null)
          {
               String[] arr = line.split("=");
           prop.setProperty(arr[0],arr[1]);
      }
          bufr.close();
          System.out.println(prop);
     }
          out.close();
          bufr.close();
 } 
4.打印流
(1)简述
    ①打印流包括:PrintStream和PrintWriter
    ②该流提供了打印方法,可将各种类型的数据都原样打印。
(2)分类
    字节打印流和字符串打印流:PrintStream和PrintWriter
①PrintStream
构造方法中可接收的参数类型:
        1、File对象。File
        2、字符串路径:String
        3、字符输出流:OutputStream
② PrintWriter
构造方法中可接受的参数类型
        1、File对象:File
        2、字符串路径:String
        3、字节输出流:OutputStream
        4、字符输出流:Writer    

代码示例:

    import java.io.*;
class  PrintStreamDemo
{
 public static void main(String[] args) throws IOException
 {
  //键盘录入
  BufferedReader bufr = 
   new BufferedReader(new InputStreamReader(System.in));

  //打印流关联文件,自动刷新
  PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true);

  String line = null;

  while((line=bufr.readLine())!=null)
  {
   if("over".equals(line))//结束字符
    break;
   out.println(line.toUpperCase());
   //out.flush();
  }

  //关流
  out.close();
  bufr.close();
 } 
}
5.序列流
(1)简述
    1、SequenceInputStream对多个流进行合并。也被称为合并流。
    2、常用构造函数:SequenceInputStream(Enumeration<?extends FileInputStream> e)
(2)常见合并多个流文件步骤
     1、创建集合,并将流对象添加进集合
     2、创建Enumeration对象,将集合元素加入。
     3、创建SequenceInputStream对象,合并流对象
     4、创建写入流对象,FileOutputStream关联写入文件
     5、利用SequenceInputStream对象和FileOutputStream对象读数据进行反复读写操作。

代码示例:


    /*
SequenceInputStream
合并流
需求:将三个文本文件中的数据合并到一个文本文件中
思路:1、创建一个Vector集合,将三个文本文件字节流添加到集合中
   2、创建Enumeration对象,创建SequnceInputStream对象关联Enumeration
   3、输出流关联新文本文件
   4、反复读写操作
*/

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

class  SequenceInputStreamDemo
{
 public static void main(String[] args)throws IOException
 {
  Vector<InputStream> ve=new Vector<InputStream>();//创建vector集合,并添加相关流对象
  ve.add(new FileInputStream("1.txt"));
  ve.add(new FileInputStream("2.txt"));
  ve.add(new FileInputStream("3.txt"));

  Enumeration<InputStream> en=ve.elements();//创建枚举对象
  SequenceInputStream sis=new SequenceInputStream(en);//合并流

  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);
  }

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

代码示例:

     public class PropertiesTest {
     public static void main(String[] args) throws IOException {   
             getAppCount();   
     }
     public static void getAppCount() throws IOException{
     //将配置文件封装成File对象。
     File confile = new File("count.properties");
    if(!confile.exists()){
         confile.createNewFile();
       }
     FileInputStream fis = new FileInputStream(confile);
     Properties prop = new Properties();
     prop.load(fis);  
     //从集合中通过键获取次数。
     String value = prop.getProperty("time");
     //定义计数器。记录获取到的次数。
     int count =0;
     if(value!=null){
     count = Integer.parseInt(value);
     if(count>=5){
         throw new RuntimeException("使用次数已到,请注册,给钱!");
         }
     }
     count++;
     //将改变后的次数重新存储到集合中。
     prop.setProperty("time", count+"");
     FileOutputStream fos = new FileOutputStream(confile);
     prop.store(fos, "");
     fos.close();
     fis.close();
     }
} 
2.序列流练习
将一个文件进行切割与合并操作。

代码示例:

import java.io.*;
import java.util.*;
class SplitFile
{
 public static void main(String[] args) throws IOException
 {
  //splitFile();
  merge();
 }
 public static void merge()throws IOException //合并文件
 {
  ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
  for(int x=1; x<=3; x++)
  {
   al.add(new FileInputStream("c:\\splitfiles\\"+x+".part"));
  }
  final Iterator<FileInputStream> it = al.iterator();
  Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()
  {
   public boolean hasMoreElements()
   {
    return it.hasNext();
   }
   public FileInputStream nextElement()
   {
    return it.next();
   }
  };
  SequenceInputStream sis = new SequenceInputStream(en);
  FileOutputStream fos = new FileOutputStream("c:\\splitfiles\\0.bmp");
  byte[] buf = new byte[1024];
  int len = 0;
  while((len=sis.read(buf))!=-1)
  {
   fos.write(buf,0,len);
  }
  fos.close();
  sis.close();
 }
 public static void splitFile()throws IOException //切割文件
 {
  FileInputStream fis =  new FileInputStream("c:\\1.bmp");
  FileOutputStream fos = null;
  byte[] buf = new byte[1024*1024];
  int len = 0;
  int count = 1;
  while((len=fis.read(buf))!=-1)
  {
   fos = new FileOutputStream("c:\\splitfiles\\"+(count++)+".part");
   fos.write(buf,0,len);
   fos.close();
  }

  fis.close();
 }
}

黑马程序员————Java基础日常笔记---IO流二

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 黑马程序员————Java基础日常笔记---IO流二 1.1 File类由来 通过IO流一可...

黑马程序员————Java基础日常笔记---IO流一

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 黑马程序员————Java基础日常笔记---IO流一 1.1 IO的由来: 先什么是IO流呢...

黑马程序员————Java基础日常笔记---IO其他流

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 黑马程序员————Java基础日常笔记---IO其他流 3.1 IO包中的其他类 3.1....

--IO流和文件操作--java学习日记8(基础知识)

IO流分为字符流和字节流两种,当要操作的对象时纯文本文件时,可以用字符流FileReader,要进一步提高效率可用BufferedReader包装一下。比如要拷贝一个文本文件,可以创建一个输入流: ...
  • qq_1991
  • qq_1991
  • 2014年07月18日 15:33
  • 701

Java基础第十八天学习日记_Util包中一些有用的类、IO流

------- android培训、java培训、期待与您交流! ---------- System:类中的方法和属性都是静态的。 常用方法: out:标准输出,默认是控制台。 in:标准...

Java基础日记———Map

——<a href=”http://www.itheima.com” target=”blank”>Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! ——- 一....

Java基础日记———异常

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——- 一.概述 (1)异常:就是程序在运行时出现不正常情况。 异常由来:问题也是现实生活中一个具体的事物...

Java基础日记———网路编程

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——- 一.概述 1.网络模型:OSI参考模型和TCP/IP模型如图: 2.网络通信三要素:IP地址,端口号,传输...

Java基础日记———String

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-一.概述 Java中万物皆对象。 字符串是一个特殊的对象。 字符串一旦初始化就不可以...

Java基础日记———多线程

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——- 一.概述 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java基础日记———IO流(下)
举报原因:
原因补充:

(最多只允许输入30个字)