黑马程序员_IO流(2)

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


第一部分:InputStream & OutputStream

/ *

字符流:FileReader FileWriter

              BufferedReaderBufferedWriter

              LineNumberReader

  |

  | 

  |   (字符数组char[]参数都变成字节数组byte[])

 \V/

字节流:InputStream OutputStream

        BufferedInputStream  Buffered OutputStream

 

【练习】通过缓冲区演示MP3的复制。并显示拷贝时间

* /

import java.io.*;

class CopyMP3Demo

{

       public static voidmain(String[] args){

            

              long start =System.currentTimeMillis();//记录起始时间

              copyMP3_2();

              long end =System.currentTimeMillis();//记录结束时间

             System.out.println("copy time :: " +(end-start)+"ms");

     

       }

 

       public static voidcopyMP3_2(){

            

             MyBufferedInputStream mbis = null;

              BufferedOutputStreambos = null;

              try{

                     mbis =new MyBufferedInputStream(new FileInputStream(

                           "G:\\原点.mp3"));

                     bos = newBufferedOutputStream(new FileOutputStream("G:\\原点2.mp3"));

                     //byte[] pic = new byte[1024];

                     int num=0;

                     while((num = mbis.myRead())!=-1){

                           bos.write(num);

                           //bos.flush();

                            //犯错笔记:不需要刷新,因为缓冲区满或者关闭流的时候会自动写入。刷新时间开销巨大。

                     }

              }

              catch(IOException e){

                     throw newRuntimeException("Failed");

              }

              finally{

                     try{

                            if(bos!=null)

                                  bos.close();

                     }

                     catch(IOException e){

                           throw new RuntimeException("WriteFailed");

                     }

                     finally{

                           try{

                                  if(mbis!=null)

                                         mbis.myClose();

                            }

                           catch (IOException e){

                                  throw newRuntimeException("ReadFailed");

                            }

                     }

              }

       }

       public static voidcopyMP3_1(){

             BufferedInputStream bis = null;

             BufferedOutputStream bos = null;

              try{

                     bis = newBufferedInputStream(new FileInputStream(

                           "G:\\原点.mp3"));

                     bos = newBufferedOutputStream(new FileOutputStream("G:\\原点2.mp3"));

                     int num=0;

                     while((num = bis.read())!=-1){

                           bos.write(num);

                           //bos.flush();

                     }

              }

              catch(IOException e){

                     throw newRuntimeException("Failed");

              }

              finally{

                     try{

                            if(bos!=null)

                                  bos.close();

                     }

                     catch(IOException e){

                           throw new RuntimeException("WriteFailed");

                     }

                     finally{

                           try{

                                  if(bis!=null)

                                         bis.close();

                            }

                           catch (IOException e){

                                   throw newRuntimeException("ReadFailed");

                            }

                     }

              }

       }

}

class MyBufferedInputStream//自定义MyBufferedInputStream类

{

       private InputStream in;

       private int counter =0, pos = 0;

       private byte[] buff =new byte[1024*4];

      MyBufferedInputStream(InputStream in){

              this.in = in;

       }

       public int myRead()throws IOException{

            

              if (counter ==0){

                     counter =in.read(buff);

                    if(counter<0)

                           return -1;

                     pos=0;

                     byte b = buff[pos];

                    counter--;

                     pos++;

                     returnb&0xff;

              }

              else if(counter>0){

                     byte b =buff[pos];

 

                    counter--;

                     pos++;

                     returnb&0xff;

              }

              return -1;

       }

       public void myClose()throws IOException{

              in.close();

       }

}

/ *

 

!!!自定义MyBufferedInputStream类中myRead()方法时:

byte: -1      --->     int:-1

0000-0000 0000-0000 0000-0000 1111-1111

return int 时强转成:

1111-1111 1111-1111 1111-1111 1111-1111

转换后仍然是int型的-1,此时判断条件不满足无法读取继续写入,造成写入失败。

只要保留后1字节,前面3个字节取零即可,方法:对应数值&0xff(255)。

这时转成:

0000-0000 0000-0000 0000-0000 1111-1111

* // *

 

 

第二部分:转换流与流操作总结

InputStreamReader & OutputStreamWriter

【需求】:通过键盘录入数据,当录入一行数据后就将该行数据进行打印。

如果录入的数据是over则停止录入。

* // *

import java.io.*;

class  IODemo3

{

       public static voidmain(String[] args) throws IOException

       {

              InputStream in =System.in;

              StringBuilder sb= new StringBuilder();

 

              while (true)

              {

                     int ch =in.read();

                    if(ch=='\r')

                           continue;

                    if(ch=='\n'){

                            if("over".equals(sb.toString()))

                                  break;

                           else{

                                  System.out.println(sb.toString());

                                  sb.delete(0,sb.length());

                            }

                     }

                     else

                           sb.append((char)ch);

              }

       }

}

* // *

 

BufferedReader类中有readLine()方法,

键盘录入的read方法是字节流InputStream的方法。

【问题】如何将字节流转成字符流,再加以使用字符流缓冲区的readLine方法?

 

【InputStreamReader】是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。

它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

构造函数:

InputStreamReader(InputStream in)

          创建一个使用默认字符集的InputStreamReader。

 

【OutputStreamWriter】是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。

它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。

构造函数:

OutputStreamWriter(OutputStream out)

          创建使用默认字符编码的OutputStreamWriter。

* // *

import java.io.*;

class  IODemo3

{

       public static voidmain(String[] args) throws IOException

       {

              InputStream in = System.in;

             //InputStreamReader将字节流InputStream转换成字符流

              BufferedReaderbr = new BufferedReader(new InputStreamReader(in));

            

              OutputStream out= System.out;

              BufferedWriter bw= new BufferedWriter(new OutputStreamWriter(out));

              String line;

              while((line =br.readLine())!=null){

                    if(line.equals("over"))

                           break;

                    bw.write(line);

                     bw.newLine();

                    bw.flush();

              }

              bw.close();

       }

}

* // *

 

1.源:键盘录入   目的:控制台

2.源:键盘录入   目的:文件

3.源:文件   目的:控制台

 

流操作的基本规律(四个明确):

 

1.明确操作的源和目的。

  源:输入流  InputStream Reader

  目的:输出流  OutputStream Writer

 

2.操作的数据是否是纯文本。

  是:字符流。

  不是:字节流。

 

3.通过两个明确判断要使用的体系,再明确要使用的具体对象,

  通过设备乱来区分:

  源设备:内存,硬盘,键盘

  目的设备:内存,硬盘,控制台

4.明确是否需要提高效率

 

【示例】:

1.【拷贝文本文件】

  源:InputStream Reader

  文本文件:Reader

  设备:硬盘

  Reader体系中操作文件的对象FileReader

 

  目的:OutputStream Writer

  文本文件:Writer

  设备:硬盘

  Writer体系中操作文件的对象FileWriter

 

  需要提高效率?BufferedReader/BufferedWriter

 

2.【键盘录入数据保存到文件中】

  源:(文本)Reader(字符流)

  设备:键盘。对应对象System.in(字节流)

  【转换】:InputStreamReader(System.in) 字节-->字符

  效率:BufferedReader

 

  目的:(文本)Writer

  设备:硬盘。文本文件。使用FileWriter

  效率:BufferedWriter

 

【扩展】:

需要把录入的数据按照指定编码表<utf-8>,将数据存入文件中

  目的:(文本)Writer

  设备:硬盘。文本文件。使用FileWriter

  效率:BufferedWriter

 

  但是存储时需要加入指定编码表。而编码表只有转换流对象可以指定。

  因此需要OutputStreamWriter

  BudderedWriter bw = newBufferedWriter(

               newOutputStreamWriter(new FileOutpurStream("d.txt"),"UTF-8"));

【总结】:

涉及到字符编码转换时,需要使用转换流。

 

【扩展】:System类中设置标准输入输出流

System.setIn(InputStream in)

System.setOut(PrintStream p)

Ex: System.setIn(new FileInputStream("abc.txt"));

       System.setOut(newPrintStream("qq.txt"));

 

【将异常信息写入日志】

* // *

import java.io.*;

import java.util.*;

import java.text.*;

class  IODemo3

{

       public static voidmain(String[] args) throws IOException

       {

              try{

                     int[] arr= new int[2];

                    System.out.println(arr[3]);

              }

              catch (Exceptione){

                     try{

                            Date d =new Date();

                           SimpleDateFormat sdf = new SimpleDateFormat(

                                                "yyyy-MM-dd HH:mm:ss");

                           String str = sdf.format(d);

 

                            PrintStream ps = newPrintStream("Exceptions.log");

                           ps.println(str);

                           System.setOut(ps);

                     }

                     catch(IOException ioe){

                            thrownew RuntimeException("LogBuiledFailed");

                     }

                    e.printStackTrace(System.out);

              }

       }

}

* // *

 

【打印系统属性信息】:

* /

import java.io.*;

import java.util.*;

class  IODemo3

{

       public static voidmain(String[] args) throws Exception

       {

              Properties props= System.getProperties();

              PrintStream ps =new PrintStream("SystemProperties.txt");

              props.list(ps);

       }

}

 

/ *

File类:

        

【练习】:使用list方法列出某目录下的所有特定后缀名(如txt)的文件。

* // *

import java.io.*;

class FileDemo

{

       public static void  main(String[] args){

            

              File dir = newFile("F:\\我的文档\\Music\\新歌");

              String[] names =dir.list(new FilenameFilter(){

                     publicboolean accept(File dir,String name){

                           return name.endsWith(".txt");

                     }

              });         

              for(Stringname:names){

                    System.out.println(name);

              }

       }

}

* // *

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

【练习】:列出某个目录下的所有层级内容,并写入文件中

* // *

import java.io.*;

class FileDemo

{

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

            

              File file = newFile("F:\\Courseware\\JAVA");

              FileWriter fw =new FileWriter("G:\\Catalog.txt");

             printLevel(file,0,"G:\\Catalog.txt");

       }

       public static StringgetLevelEx(int level){ //写入txt文件

              StringBuilder sb= new StringBuilder();

            

             sb.append("|---");

              for (int i =0;i<level ;i++ )

              {

                    sb.insert(0,"|   ");

              }

              returnsb.toString();

       }

 

       public static voidprintLevel(File dir, int level,String str) throws IOException{

            

              BufferedWriterfw = new BufferedWriter(new FileWriter(str,true));

              fw.write(getLevelEx(level)+dir.getName());

              fw.newLine();

              fw.flush();

 

              level++;

              File[] files=dir.listFiles();

              for (intl=0;l<files.length ;l++ )

              {

                     if(files[l].isDirectory())

                           printLevel(files[l],level,str);//递归调用

                     else{

                           fw.write(getLevelEx(level)+files[l].getName());

                           fw.newLine();

                     }

              }

              fw.close();

       }

}

【注意】:可以考虑使用集合装入特定目录下的文件与文件夹,然后再取出文件,获得路径,最后写入文本文件中。

* // *

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

【删除一个带内容的目录】:

删除原理:

在windows中,删除目录是从里面往外面删除的。

既然是层次的,就可以利用递归调用。

* // *

import java.io.*;

class FileDemo

{

       public static voidmain(String[] args) throws Exception{

              File dir = newFile("F:\\Courseware\\JAVA\\file");

              removeDir(dir);

       }

       public static void removeDir(Filedir){

 

            

              File[] files =dir.listFiles();

              for(File f :files){

                    if((!f.isHidden()) && f.isDirectory()){ //避开隐藏文件

                           removeDir(f);

                     }

                     else{

                           System.out.println(f.toString()+"------FILE------"+f.delete());

                     }

              }

             System.out.println(dir.toString()+"::::::DIR::::::"+dir.delete());

              dir.delete();

       }

}

* // *

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

【练习】:将练习目录下的java文件列成清单写入txt文件中

* /

import java.util.*;

import java.io.*;

class FileDemo

{

       public static voidmain(String[] args){

              File dir = newFile("F:\\Courseware\\JAVA");

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

            

             fileToList(dir,list);

             writeToText(list,newFile(dir,"java_list.txt"),"java");

            

       }

       //先把指定目录dir下的文件或文件夹装入集合list中

       public static voidfileToList(File dir,List<File> list){

            

              File[] files =dir.listFiles();

              for(File f:files){

                    if(f.isDirectory())

                            fileToList(f,list);

                     else{

                           list.add(f);

                     }

              }

       }

       //list集合作为容器装在指定文件,desFile参数为目的文件,type为保留文件的后缀名

       public static voidwriteToText(List<File> list,File desFile,String type){

            

              BufferedWriterbw =null;

              try{

                     bw = newBufferedWriter(new FileWriter(

                           desFile.toString()));

                    Iterator<File> it = list.iterator();

                     while(it.hasNext())

                     {

                           File f = it.next();

                           if(f.getName().endsWith("."+type)){

                                         bw.write(f.getAbsolutePath().toString());

                                         bw.newLine();

                                         bw.flush();

                            }

                     }

              }

              catch(IOException e){

                     throw newRuntimeException("WriterFailed");

              }

              finally{

                    if(bw!=null){

                           try{bw.close();}

                           catch (IOException e){

                                  throw new RuntimeException("CloseFailed");}

                     }

              }   

       }

}

 


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值