黑马程序员-9 输入输出流IO

时间:2021-04-17 10:56:13

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

IO的设计通过三个明确来完成。

1,明确源和目的。
源:输入流。InputStream Reader
目的:输出流。OutputStream Writer。
2,操作的数据是否是纯文本。
是:字符流。
不是:字节流。
3,当体系明确后,在明确要使用哪个具体的对象。
通过设备来进行区分:
源设备:内存,硬盘。键盘
目的设备:内存,硬盘,控制台。

===================================================================

范例1

1,将一个文本文件中数据存储到另一个文件中。复制文件。
源:因为是源,所以使用读取流。InputStream Reader
是不是操作文本文件。
是!这时就可以选择Reader
这样体系就明确了。
接下来明确要使用该体系中的哪个对象。
明确设备:硬盘。上一个文件。
Reader体系中可以操作文件的对象是 FileReader
是否需要提高效率:是!。加入Reader体系中缓冲区 BufferedReader.
FileReader fr = new FileReader("a.txt");
BufferedReader bufr = new BufferedReader(fr);

目的:OutputStream Writer
是否是纯文本。
是!Writer。
设备:硬盘,一个文件。
Writer体系中可以操作文件的对象FileWriter。
是否需要提高效率:是!。加入Writer体系中缓冲区 BufferedWriter
FileWriter fw = new FileWriter("b.txt");
BufferedWriter bufw = new BufferedWriter(fw);

//注意异常处理

import java.io.*;

public class File2FileDemo {
    public static void main(String[] args) {
        copy();
    }
    
    public static void copy(){
        BufferedReader bufr = null;
        BufferedWriter bufw = null;
        try {
            bufr = new BufferedReader(new FileReader("c:\\demo1.txt"));
            bufw = new BufferedWriter(new FileWriter("c:\\demo2.txt"));
            String str = null;
            while((str = bufr.readLine()) !=null){
                bufw.write(str,0,str.length());
                bufw.newLine();
                bufw.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally{    
            try {
                if(bufr != null) bufr.close();
                if(bufw != null) bufw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }    
            System.out.println("end");
        }
    }
}

 

===========================================================


重载输入输出流实现文件复制

class  TransStreamDemo2
{
    public static void main(String[] args) throws IOException
    {
        System.setIn(new FileInputStream("PersonDemo.java"));

        System.setOut(new PrintStream("zzz.txt"));

        //键盘的最常见写法。
        BufferedReader bufr = 
                new BufferedReader(new InputStreamReader(System.in));

        
        BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

        String line = null;

        while((line=bufr.readLine())!=null)
        {
            if("over".equals(line))
                break;
            bufw.write(line.toUpperCase());
            bufw.newLine();
            bufw.flush();
        }
        bufr.close();
    }
}

 

====================================================
自定义的读取缓冲区(理解原理)

 自定义的读取缓冲区,其实就是模拟一个BufferedReader
 分析:
 缓冲区中无非就是封装了一个数组,并对外提供了更多的方法对数组进行访问。
 其实这些方法最终操作的都是数组的指针。
 缓冲的原理:
 从源中获取一批数据装入缓冲区中,然后从缓冲区中不断取出一个一个的数据。
 当此次取完后,再从源中继续取一批数据进入缓冲区。
 当源中的数据取光时,用-1作为结束标记。  

import java.io.FileReader;  
import java.io.IOException;  

public class MyBufferedReader {  
    private FileReader r;  
  
    //定义一个数组作为缓冲区  
    private char[] buf=new char[1024];  
    //定义一个指针,用于操作数组中的元素,当操作到最后一个元素后,指针归零  
    private int pos=0;  
      
    //定义一个计数器,用于记录缓冲区中的数据个数,当该数据减到0,  
    //就从源中继续获取数据到缓冲区中  
    private int count=0;  
      
    public MyBufferedReader(FileReader r) {  
        this.r = r;  
    }  
  
    /** 
     * 该方法从缓冲区中一次取一个字符 
     * @return 
     * @throws IOException 
     */  
    public int myRead() throws IOException {  
  
        if(count==0){  
            count=r.read(buf);//从源中获取数据  
            pos=0;  
        }  
        if(count<0)  
            return -1;  
          
        char ch=buf[pos++];  
          
        count--;  
        return ch;  
          
        /*//1.从源中取出一批数据到缓冲区中,要先做判断, 
        //只有计数器为0时才 需要从源中获取数据 
        if(count==0){ 
            count=r.read(buf); 
             
            if(count<0) 
                return -1; 
             
            //每次获取数据到缓冲区后,角标归零 
            pos=0; 
            char ch=buf[pos]; 
             
            pos++; 
            count; 
            return ch; 
        }*/  
          
    }  
  
    public String myReadLine() throws IOException {  
  
        StringBuilder sb=new StringBuilder();  
        int ch=0;  
        while((ch=myRead())!=-1){  
            if(ch=='\r')  
                continue;  
            if(ch=='\n')  
                return sb.toString();  
              
            //将从缓冲区中读到的字符存储到缓存行数据的缓冲区中  
            sb.append((char)ch);  
        }  
        if(sb.length()!=0)  
            return sb.toString();  
        return null;  
    }  
  
    public void myClose() throws IOException {  
        r.close();  
    }  
  
}  

 

=========================================================

打印错误日志例

import java.io.*;
import java.util.*;
import java.text.*;
class  ExceptionInfo
{
    public static void main(String[] args)throws IOException 
    {
        try
        {
            int[] arr = new int[2];
            System.out.println(arr[3]);
        }
        catch (Exception e)
        {
            
            try
            {
                Date d = new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String s = sdf.format(d);

                PrintStream ps = new PrintStream("exeception.log");
                ps.println(s);
                System.setOut(ps);

                
            }
            catch (IOException ex)
            {
                throw new RuntimeException("日志文件创建失败");
            }
            e.printStackTrace(System.out);
        }
    }
}

 

==============================================
打印流:
该流提供了打印方法,可以将各种数据类型的数据都原样打印。

字节打印流:
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();

    }    
}