黑马程序员_总结笔记之IO流(1)_基本流

  • 字符流Reader Writer
    • FileReader & FileWriter
      • 读取文件对象必须存在

      • 创建一个字节数组来接收读取的数据
      • 例如:copy一个文本文件,包含异常处理代码:
        import java.io.*;
        public class FileReaderAndFileWriterDemo {
        
        	public static void main(String[] args) {
        		// TODO Auto-generated method stub
        		Reader reader = null;
        		Writer writer = null;
        		try{
        			reader = new FileReader("C:\\Users\\Desdemona\\Documents\\JavaWork\\IO\\File1\\aaa.txt");
        			writer = new FileWriter("C:\\Users\\Desdemona\\Documents\\JavaWork\\IO\\File2\\aaa.txt");
        			char[] ch = new char[1024];
        			int len = 0;
        			while((len=reader.read(ch))!=-1)
        				writer.write(ch,0,len);
      •  System.out.println("OK");
        		}
        		catch(IOException e){
        			e.printStackTrace();
        		}
        		finally{
        			if(reader != null){
        				try{
        					reader.close();
        				}
        			catch(IOException e){
        				e.printStackTrace();
        			}
        			}
        			if(writer != null){
        				try{
        					writer.close();
        				}
        			catch(IOException e){
        				e.printStackTrace();
        			}
        			}
        		}
        
        	}
        
        }
        

    • BufferedReader&BufferedWriter
      • 创建缓冲区之前必须要有流对象,所以缓冲区没有无参构造方法,必须传入一个流对象
      • 提高流的操作效率
      • 关闭缓冲区,就是关闭缓冲区中的流对象
      • BufferedWriter:
        • 用缓冲区记得刷新
        • newLine();
      • BufferedReader:
        • 行的高效读取:String readLine();【不包含行终止符】
        • 有个子类 LineNumberReader,有get和set LineNumber的方法

      • 用缓冲区复制文本文件:
        import java.io.*;
        public class BufferedReaderAndBufferedWriterDemo {
        
        	public static void main(String[] args) throws IOException {
        		// TODO Auto-generated method stub
        		BufferedReader bufr = new BufferedReader(new FileReader("C:\\Users\\Desdemona\\Documents\\JavaWork\\IO\\File1\\PicServer.java"));
        		BufferedWriter bufw = new BufferedWriter(new FileWriter("C:\\Users\\Desdemona\\Documents\\JavaWork\\IO\\File2\\PicServer.java"));
        		String line = null;
        		while((line=bufr.readLine())!=null){
        			bufw.write(line);
        			bufw.newLine();  //换行
        			bufw.flush();  //刷新
        		}
        		bufr.close();
        		bufw.close();
        	}
        
        }

      • FileReader与BufferedReader引出装饰设计模式:
        • 基于已有类进行功能增强
        • 通过构造方法接收被装饰的类
        • 例如自己写的MyBufferedReader装饰了Reader,以及自己写的LineNumberReader:
          import java.io.*;
          public class MyBufferedReader {
          	private Reader r;
          
          	public MyBufferedReader(Reader r) {
          		super();
          		this.r = r;
          	}
          	
          	public String myReadLine() throws IOException{
          		StringBuilder sb = new StringBuilder();
          		int ch = 0;
          		while((ch=r.read())!=-1){
          			if(ch == '\r')
          				continue;
          			if(ch == '\n')
          				return sb.toString();
          			else
          				sb.append((char)ch);
          		}
          		if(sb.length()>0)
          			return sb.toString();
          		return null;
          		
          	}
          	
          	public void myClose() throws IOException{
          		r.close();
          	}
          	
          }
          
          
          
          import java.io.*;
          
          
          public class MyLineNumberReader extends MyBufferedReader {
          	private int lineNumber;
          
          	public MyLineNumberReader(Reader r) {
          		super(r);
          		this.lineNumber = 0;
          		// TODO Auto-generated constructor stub
          	}
          
          	@Override
          	public String myReadLine() throws IOException {
          		// TODO Auto-generated method stub
          		lineNumber++;
          		return super.myReadLine();
          	}
          
          	public int getLineNumber() {
          		return lineNumber;
          	}
          
          	public void setLineNumber(int lineNumber) {
          		this.lineNumber = lineNumber;
          	}	
          
          }
          

        • 继承和装饰的区别:装饰比继承灵活,避免了继承体系的臃肿。装饰类和被装饰类属于同体系,通常都继承同一个父类,比如A1、A2、A3、AA都继承A,AA装饰A1~A3
  • 字节流InputStream和OutputStream
    • OutputStream:write(byte[])【没用缓冲区时不需要刷新,因为都是一个一个字节写的】
    • FileInputStream和FileOutputStream
      • 三种读文件的方式:1.一个一个字节读 2.字节数组缓冲区读 3.用available()方法获取缓冲区长度,但小心内存溢出
      • 例:复制图片
        import java.io.*;
        
        public class FileInputStreamAndFileOutputStreamDemo {
        
        	public static void main(String[] args) throws IOException{
        		// TODO Auto-generated method stub
        		InputStream in = new FileInputStream("C:\\Users\\Desdemona\\Documents\\JavaWork\\IO\\File1\\pizza.jpg");
        		OutputStream out = new FileOutputStream("C:\\Users\\Desdemona\\Documents\\JavaWork\\IO\\File2\\pizza.jpg");
        		byte[] b = new byte[1024];
        		int len = 0;
        		while((len=in.read(b))!=-1)
        			out.write(b, 0, len);
        		in.close();
        		out.close();
        
        	}
        
        }

        问:用字符流可以复制吗 答:复制完的图片可能打不开 如果字节查编码表查不到,那就会用相似的编码代替,最后文件的内容改变
    • 字节流缓冲流BufferedInputStream和BufferedOutputStream:
      • BufferedInputStream:使用时不用定义缓冲区,直接读取int
        public static void main(String[] args) throws IOException{
        		// TODO Auto-generated method stub
        		BufferedInputStream in = new BufferedInputStream(new FileInputStream("C:\\Users\\Desdemona\\Documents\\JavaWork\\IO\\File1\\aaa.txt"));
        		int b = 0;
        		while((b=in.read())!=-1)
        			System.out.print((char)b);
        	}

      • MyBufferedInputStream解释了缓冲区的读取方法:先读到字节数组里,然后一个一个取出
        import java.io.*;
        public class MyBufferedInputStream {
        	private InputStream in;
        	private byte[] buf=new byte[1024];
        	private int count, off;
        	
        	public MyBufferedInputStream(InputStream in) {
        		super();
        		this.in = in;
        	}
        	
        	public int myRead() throws IOException{
        		if(count==0){
        			count = in.read(buf);
        			if(count<0)
        				return -1;
        			count--;
        			return buf[off]&255;
        		}
        		else if(count>0){
        			count--;
        			off++;
        			return buf[off]&255;
        		}
        		return -1;
        	}
        	
        	public void myClose() throws IOException{
        		in.close();
        	}
        	
        }
        

        注意int read() 方法将读出的字节补位为32位,write(int)方法将参数取最低八位写入,这是为了避免出现11111111,即-1,所以自己定义的myRead()方法要防止出现-1,所以&255
  • 转换流InputStreamReader与OutputStreamWriter
    • 字节流通向字符流的桥梁:InputStreamReader
      • 由键盘录入一行并输出问题想到readLine()方法,但System.in是InputStream,而readLine()是BufferedReader的方法;因此要在字节字符流之间转换
      • 例:从键盘读入一行数据并转换成大写输出,如果读到over,程序停止
        	public static void main(String[] args) throws IOException{
        		// TODO Auto-generated method stub
        		BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));
        		String s = null;
        		while((s=bfr.readLine())!=null){
        			if("over".equals(s))
        				break;
        			System.out.println(s.toUpperCase());
        			
        		}
        		bfr.close();
        
        	}
        
    • 字符流通向字节流的桥梁:OutputStreamWriter
      • 例:修改以上程序,用字节流输出:
        	public static void main(String[] args) throws IOException{
        		// TODO Auto-generated method stub
        		BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));
        		BufferedWriter bfw = new BufferedWriter(new OutputStreamWriter(System.out));
        		String s = null;
        		while((s=bfr.readLine())!=null){
        			if("over".equals(s))
        				break;
        			bfw.write(s.toUpperCase());
        			bfw.newLine();
        			bfw.flush();
        			
        		}
        		bfr.close();
        		bfw.close();
        
        	}

        别忘记刷新~~~
    • 标准输入输出转换流写法:BfferedReader bufr =
      new BufferedReader(new InputStreamReader(System.in));

      new BufferedWriter bufw =
      new BufferedWriter(new OutputStreamWriter(System.out));
  • 总结:流操作规律
    1. 明确源和目的
    2. 操作的数据是否纯文本
    3. 明确使用哪个具体的对象(内存?硬盘?键盘/控制台?)
  • 插曲1:修改标准输入输出设备
    • System.setIn(InputStream)
    • System.setOut(PrintStream)
  • 插曲2:异常的日志信息
                    SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    		String s = date.format(new Date());
    		
    		PrintStream ps = new PrintStream("log.txt");
    		ps.println(s);
    		System.setOut(ps);
    		
    		new Exception().printStackTrace(ps);
  • 插曲3:获取系统信息
    Properties prop = System.getProperties();
    		prop.list(System.out);
    list方法接收PrintStream参数


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值