java io 详解与DEMO

来源:互联网 发布:教育培训网站源码 编辑:程序博客网 时间:2024/05/29 12:56

一、java io 设计模式

JDK的I/O包中就主要使用到了两种设计模式:Adatper模式和Decorator模

设计模式本人了解浅显,在这不做任何说明,有兴趣的朋友可以自己研究一下,因为java io 很好运用了这两种设计模式。

二、java io 详解与DEMO

/**
 *
 * @author orderDong
 * @version 1.0
 * @description 流演示与总结
 * @since 20130305
 * @description 一层:基本字节与字符数据流
 *     二层:封装数据流,建立一层数据流之上
 *     三层:粗广数据流
 */
public class FileUtil {
 private static final String module = FileUtil.class.getName();
 /**
  *
  * 字节流:InputStream 直接子类 AudioInputStream, ByteArrayInputStream, FileInputStream,
  * FilterInputStream, InputStream, ObjectInputStream, PipedInputStream, SequenceInputStream,
  *  StringBufferInputStream and so on;
  * 字符流:InputStreamReader OutputStreamWriter BufferedReader, LineNumberReader,
  * CharArrayReader, InputStreamReader, FileReader, FilterReader, PushbackReader,
  * PipedReader, StringReader, Writer and so on ;
  */
 /**
  * 创建文件夹
  */
 @Test
 public void createFolder(){
  String  result = null;
  Boolean resultBoo = false;
  String fileName = "D:"+File.separator+"FileUtil";
  File file = new File(fileName);
  if(file.exists()){
   System.out.println("file existe!");
  }else{
   resultBoo = file.mkdir();
   if(resultBoo){
    System.out.println("excute result:  "+resultBoo);
   }else{
    System.out.println("excute result:  "+resultBoo);
   }
  }
 }
 /**
  * 创建文件
  */
 @Test
 public void createFile(){
  String  result = null;
  Boolean resultBoo = false;
  String fileName = "D:"+File.separator+"FileUtil"+File.separator+"test.docx";
  File file = new File(fileName);
  if(file.exists()){
   System.out.println("file existe!");
  }else{
   try {
    resultBoo = file.createNewFile();
   } catch (IOException e) {
    e.printStackTrace();
   }
   if(resultBoo){
    System.out.println("excute result:  "+resultBoo);
   }else{
    System.out.println("excute result:  "+resultBoo);
   }
  }
 }
 /**
  * 列出所有文件夹及文件
  */
 @Test
 public void listFolder() {
        String fileName="D:"+File.separator;
        File f=new File(fileName);
        String[] str=f.list();
        for (int i = 0; i < str.length; i++) {
            System.out.println(str[i]);
        }
    }
 /**
  * 列出指定文件夹下所有文件
  */
 @Test
 public void listFileAll() {
        String fileName="D:"+File.separator+"360Downloads";
        File f=new File(fileName);
        print(f);
    }
    public void print(File f){
        if(f!=null){
            if(f.isDirectory()){
                File[] fileArray=f.listFiles();
                if(fileArray!=null){
                    for (int i = 0; i < fileArray.length; i++) {
                        //递归调用
                        print(fileArray[i]);
                    }
                }
            }
            else{
                System.out.println(f);
            }
        }
    }
    /**
     * 字节流byte
     * 对随机访问文件的读取和写入
     */
    @Test
    public void RandomWriteFile(){
     String fileName = "D:"+File.separator+"FileUtil"+File.separator+"test.txt";
     File file = new File(fileName);
     try {
   RandomAccessFile raf = new RandomAccessFile(file, "rw");
   raf.writeBytes("Apache OFBiz Apache");
   raf.close();
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   System.out.println(e.getStackTrace());
  }
    }
    /**
     * 字节流byte
     * 对随机访问文件的读取和写入
     * 随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。
     * 存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,
     * 并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;
     * 输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。
     * 写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过 getFilePointer 方法读取,
     * 并通过 seek 方法设置
     */
    @Test
    public void RandomReaderFile(){
     String fileName = "D:"+File.separator+"FileUtil"+File.separator+"test.txt";
     File file = new File(fileName);
     try {
   RandomAccessFile raf = new RandomAccessFile(file, "rw");
   byte [] byt = new byte[100];
   int i = 0 ;
   while((i=raf.read(byt, 0, byt.length))!=-1){
    System.out.println("read byte io test is :"+new String(byt,"gb2312"));
   }
   raf.close();
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   System.out.println(e.getStackTrace());
  }
    }
    /**
     * 字节流byte
     * FileInputStream 从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境。
     * 此类是过滤输出流的所有类的超类。这些流位于已存在的输出流(基础 输出流)之上,
     * 它们将已存在的输出流作为其基本数据接收器,但可能直接传输数据或提供一些额外的功能。
     * FilterOutputStream 类本身只是简单地重写那些将所有请求传递给所包含输出流的 OutputStream 的所有方法。
     * FilterOutputStream 的子类可进一步地重写这些方法中的一些方法,并且还可以提供一些额外的方法和字段。
     */
    @Test
    public void FileInputReadWriteFile(){
     String fileName = "D:"+File.separator+"FileUtil"+File.separator+"love.txt";
     String fileName1 = "D:"+File.separator+"FileUtil"+File.separator+"love1.txt";
     File file = new File(fileName);
     try {
   FileInputStream fis = new FileInputStream(file);
   FileOutputStream fos = new FileOutputStream(new File(fileName1));
   byte [] byt = new byte[100];
   int i = 0 ;
   while((i=fis.read(byt,0,byt.length))!=-1){
    fos.write(byt, 0, byt.length);
    System.out.println("read byte io test is :"+new String(byt,"gbk"));
   }
   fis.close();
   fos.close();
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (UnsupportedEncodingException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
    }
    /**
     * 字节流
     * BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持 mark 和 reset 方法的能力。
     * 在创建 BufferedInputStream 时,会创建一个内部缓冲区数组。在读取或跳过流中的字节时,
     * 可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。mark 操作记录输入流中的某个点,
     * reset 操作使得在从包含的输入流中获取新字节之前,再次读取自最后一次 mark 操作后读取的所有字节。
     */
    @Test
    public void BufferFileInputReadWrite(){
     String fileName = "D:"+File.separator+"FileUtil"+File.separator+"love.txt";
     String fileName1 = "D:"+File.separator+"FileUtil"+File.separator+"boslove1.txt";
     File file = new File(fileName);
     try {
   InputStream fis = new FileInputStream(file);
   OutputStream fos = new FileOutputStream(new File(fileName1));
   BufferedInputStream bis = new BufferedInputStream(fis);
   BufferedOutputStream bos = new BufferedOutputStream(fos);
   byte [] byt = new byte[100];
   int i = 0 ;
   while((i=bis.read(byt,0,byt.length))!=-1){
    bos.write(byt, 0, byt.length);
    System.out.println("read byte io test is :"+new String(byt,"gb2312"));
   }
   fis.close();
   fos.close();
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (UnsupportedEncodingException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
    }
    /**
     * 用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。
     * 要自己指定这些值,可以先在 FileInputStream 上构造一个 InputStreamReader。
     * 默认字符编码和默认字节缓冲,可有针对性的使用,这也使得读取写入有限制
     */
    @Test
    public void FileReaderWriterFile(){
     String fileName = "D:"+File.separator+"FileUtil"+File.separator+"test.txt";
     String fileName1 = "D:"+File.separator+"FileUtil"+File.separator+"filewriterlove1.txt";
     File file = new File(fileName);
     try {
      FileReader fr = new FileReader(file);
   FileWriter fw = new FileWriter(new File(fileName1));
   char [] ch = new char[100];
   String str = null;
   int i = 0 ;
   while((i=fr.read(ch, 0, ch.length))!=-1){
    fw.write(ch, 0, ch.length);
    System.out.println("read byte io test is :"+new String (ch, 0, ch.length));
   }
   fr.close();
   fw.close();
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (UnsupportedEncodingException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
    }
    /**
     * InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。
     * 它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。
     * 每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。
     * 要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。
     * 为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。例如:
     * BufferedReader in= new BufferedReader(new InputStreamReader(System.in));
     */
    @Test
    public void inputStreamReaderWriterFile(){
     String fileName = "D:"+File.separator+"FileUtil"+File.separator+"love.txt";
     String fileName1 = "D:"+File.separator+"FileUtil"+File.separator+"inputreaderwriterlove1.txt";
     File file = new File(fileName);
     try {
      InputStream is = new FileInputStream(file);
      InputStreamReader isr = new InputStreamReader(is,"gbk");
      OutputStream os = new FileOutputStream(new File(fileName1));
      OutputStreamWriter isw = new OutputStreamWriter(os,"gbk");
   char [] ch = new char[100];
   String str = null;
   int i = 0 ;
   while((i=isr.read(ch, 0, ch.length))!=-1){
    isw.write(ch, 0, ch.length);
    System.out.println("read byte io test is :"+new String (ch, 0, ch.length));
   }
   isr.close();
   isw.close();
   is.close();
   os.close();
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (UnsupportedEncodingException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
    }
    /**
     * 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
     * 可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。
     * 通常,Reader 所作的每个读取请求都会导致对底层字符或字节流进行相应的读取请求。因此,建议用 BufferedReader 包装所有其 read() 操作可能开销很高的 Reader(如 FileReader 和 InputStreamReader)。例如,
     * BufferedReader in = new BufferedReader(new FileReader("foo.in"));
     * 将缓冲指定文件的输入。如果没有缓冲,则每次调用 read() 或 readLine() 都会导致从文件中读取字节,并将其转换为字符后返回,而这是极其低效的。
     * 通过用合适的 BufferedReader 替代每个 DataInputStream,可以对将 DataInputStream 用于文字输入的程序进行本地化

     */
    @Test
    public void BufferedReaderWriterFile(){
     String fileName = "D:"+File.separator+"FileUtil"+File.separator+"love.txt";
     String fileName1 = "D:"+File.separator+"FileUtil"+File.separator+"bufferedwriterlove1.txt";
     File file = new File(fileName);
     try {
      InputStream is = new FileInputStream(file);
      InputStreamReader isr = new InputStreamReader(is,"gbk");
      OutputStream os = new FileOutputStream(new File(fileName1));
      OutputStreamWriter isw = new OutputStreamWriter(os,"gbk");
      BufferedReader br = new BufferedReader(isr);
      BufferedWriter bw = new BufferedWriter(isw);
   /*
    * 有两种读取方式,第一种字符读取
    */
      /*char [] ch = new char[100];
   String str = null;
   int i = 0 ;
   while((i=isr.read(ch, 0, ch.length))!=-1){
    isw.write(ch, 0, ch.length);
    System.out.println("read byte io test is :"+new String (ch, 0, ch.length));
   }*/
      /*
       * 第二种,针对文本,整行读取
       */
      String str = null;
   while((str=br.readLine())!=null){
    bw.write(str, 0, str.length());
    System.out.println(str);
   }
   br.close();
   bw.close();
   isr.close();
   isw.close();
   is.close();
   os.close();
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (UnsupportedEncodingException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
    }
    /**
     * DataInputStream  DataOutputStream
     * 字节流
     * 数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。
     * 应用程序可以使用数据输出流写入稍后由数据输入流读取的数据。
     * DataInputStream 对于多线程访问不一定是安全的。 线程安全是可选的,它由此类方法的使用者负责。
     */
   
    /**
     * 字节流
     * FilterInputStream FilterOutputStream
     * public class FilterInputStream extends InputStream FilterInputStream 包含其他一些输入流,
     * 它将这些流用作其基本数据源,它可以直接传输数据或提供一些额外的功能。
     * FilterInputStream 类本身只是简单地重写那些将所有请求传递给所包含输入流的 InputStream 的所有方法。
     * FilterInputStream 的子类可进一步重写这些方法中的一些方法,并且还可以提供一些额外的方法和字段。
     * 直接已知子类: BufferedInputStream, CheckedInputStream, CipherInputStream, DataInputStream,
     * DeflaterInputStream, DigestInputStream, InflaterInputStream, LineNumberInputStream,
     * ProgressMonitorInputStream, PushbackInputStream
     *
     * 参见FileInputStream方式的DEMO
     */
   
    /**
     * 字节流
     *  PipedInputStream PipedOutputStream
     *  管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。
     *  通常,数据由某个线程从 PipedInputStream 对象读取,并由其他线程将其写入到相应的 PipedOutputStream。
     *  不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。
     *  管道输入流包含一个缓冲区,可在缓冲区限定的范围内将读操作和写操作分离开。
     *  如果向连接管道输出流提供数据字节的线程不再存在,则认为该管道已损坏。
     * 
     * 管道输出流的构造方法是传入的 管道输出流
     * 参见FileInputStream方式的DEMO
     */
   
    /**
     * Z字节流
     * SequenceInputStream
     * SequenceInputStream 表示其他输入流的逻辑串联。它从输入流的有序集合开始,
     * 并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,
     * 直到到达包含的最后一个输入流的文件末尾为止。
     *
     * 参见FileInputStream方式的DEMO
     */
   
    /**
     * 对象输入输出流
     * ObjectInputStream  ObjectOutputStream
     * ObjectInputStream ObjectOutputStream 针对基本数据,引用类型和对象进行数据传输
     * 只有支持 java.io.Serializable 或 java.io.Externalizable 接口的对象才能从流读取
     * 
     * 详见JDK API 上面有例子
     */
}

当然,java io 不止这些,还有很多,在这就不一一列举了,大家可以参考JDK API,如果有些地方有问题,也请大家多多指导!