「Java基础」IO流

IO流

1 缓冲区的出现

缓冲区的出现是为了提高流的操作效率而出现的,避免了频繁的读写,但是缓冲区的服务对象是流,如果没有了流,那么缓冲区的存在会失去意义。

2 BufferedWriter与BufferedReader

关于BufferedWriter类,它的作用是为了在写入之前暂时存储字符,它的一般用法有:
.write(),写入字符进入缓冲区方法
.newLine(),换行操作
.flush(),将缓冲区内容写入目标文件
.close(),关闭缓冲区资源,在.close()之前,如果没有执行.flush(),则.close()会自动执行关闭内容

// 一个例子
import java.io.*;

class  BufferedWriterDemo
{
	public static void main(String[] args) throws IOException
	{
		//创建一个字符写入流对象。
		FileWriter fw = new FileWriter("buf.txt");
		BufferedWriter bufw = new BufferedWriter(fw);

		for(int x=1; x<5; x++)
		{
			bufw.write("abcd"+x);
			bufw.newLine();
			bufw.flush();
		}
		//bufw.flush();
		bufw.close();
	}
}

关于BufferedReader类,一个基本的功能.readLine(),可以分行读取文本内容,但是也需要FileReader对象,将它传入BufferedReader()中,装饰器的做法

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

public class BufferedReaderDemo {
    public static void main(String[] args) throws IOException
    {
        FileReader FR = new FileReader("demo.txt");
        BufferedReader bfr = new BufferedReader(FR);// 加入缓冲区

        String line = null;

        while ((line=bfr.readLine())!=null)
        {
            System.out.println(line);
        }
    }
}

3 一个例子:拷贝文件的内容

内容描述:通过缓冲区复制一个文件

import java.io.*;

public class CopyTextByBuf3 {
    public static void main(String[] args)
    {
        BufferedReader bufr = null;
        BufferedWriter bufw = null;
        try
        {
            bufr = new BufferedReader(new FileReader("demo.txt"));// 在缓冲器中添加读入器,读入demo.txt
            bufw = new BufferedWriter(new FileWriter("demo_copy.txt")); // 在缓冲器中添加写入器,拷贝的目标文件 demo_copy.txt
            String line = null;
            while ((line=bufr.readLine())!=null) // 按行写入
            {
                bufw.write(line);
                bufw.newLine(); // 加入换行
                bufw.flush(); // 写入
            }
        }
        catch(IOException e)
        {
            throw new RuntimeException("读写失败");
        }
        finally {
            try
            {
                if(bufr!=null)
                    bufr.close(); // 关闭资源
            }
            catch (IOException e)
            {
                throw new RuntimeException("关闭bufr失败");
            }
            try {
                if(bufw!=null)
                    bufw.close(); // 关闭资源
            }
            catch (IOException e)
            {
                throw new RuntimeException("关闭bufw失败");
            }
        }
    }
}

4 实现BufferedReadLine()方法

5 装饰器设计模式、与继承的区别

装饰器比较继承来说,可以先通过一个例子来描述:

public class PersonDemo {
    public static void main(String[] args)
    {
        Person p = new Person(); 
        // 装饰器写法:将普通人对象传入超级人
        SuperPerson sp = new SuperPerson(p); 
        sp.SuperEat();
        p.eat();
    }
}

class Person
{
    public void eat()
    {
        System.out.println("普通方法:坐着吃饭");
    }
}

class SuperPerson
{
    private Person p;
    SuperPerson(Person p) // 普通对象传入超级对象类中
    {
        this.p = p;
    }
    public void SuperEat()
    {
        System.out.println("升级方法:倒立吃饭");
    }
}

打印结果:
升级方法:倒立吃饭
普通方法:坐着吃饭
————分割线 ————

这里有一个问题,既然装饰器可以写一个新的方法“超级吃饭”,那么为什么不用继承的方法,复写父类方法中的“普通方法”呢?

回答是当然可以使用继承的方法来复写父类方法,但是这样的做法会让原本的继承体系更加臃肿,而使用装饰器写法,改变了类与类之间的关系。

将继承关系转化为了组合关系

例如:

MyReader//专门用于读取数据的类。
	|--MyTextReader
		|--MyBufferTextReader // 继承
	|--MyMediaReader
		|--MyBufferMediaReader // 继承
	|--MyDataReader
		|--MyBufferDataReader // 继承

MyReader//专门用于读取数据的类。
	|--MyTextReader
	|--MyMediaReader
	|--MyDataReader
	|--MyBufferReader //装饰器

装饰器和这些类是同一级的,关于装饰器的一个比喻:装饰者做的事情就像是面包店里的甜点师,向不同的面包上涂抹同一种味道的奶油。

总结:

  • 装饰者将继承关系转化为了组合关系,消解了类与子类之间的耦合性
  • 装饰者类与其它类之间为同级关系,它们都属于同一个体系
  • 装饰者提供了某个方法的更强的功能
  • 装饰者通过构造函数接收对象

6 一个例子:自定义一个行计数器

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

public class MyLineNumberReader {
    private Reader R;
    private int LineNum;
    MyLineNumberReader(Reader R)
    {
        this.R = R; // 
    }
    public String MyReadLine() throws IOException
    {
        LineNum++; // 调用自增计数器

        StringBuilder sb = new StringBuilder();
        int ch = 0;

        while ((ch=R.read())!=-1) // 单个读取
        {
            if (ch=='\r') // 遇到\r,跳过
                continue;
            if (ch=='\n') // 遇到换行标志,返回字符串
                return sb.toString(); 
            else
                sb.append((char)ch);  // 添加字符串进入StringBuilder
        }
        if (sb.length()!=0)
            return sb.toString(); // 如果结尾没有\n时,也返回字符串
        return null;
    }
    public void setLineNumber(int LineNum)
    {
        this.LineNum = LineNum;
    }
    public int getLineNumber()
    {
        return LineNum;
    }
    public void myClose() throws IOException
    {
        R.close();
    }
}

class MyLineNumberReaderDemo
{
    public static void main(String[] args) throws IOException
    {
        // 自定义
        FileReader fr = new FileReader("/Users/zy/zy_Javase/my_work/day19/19/src/BufferedReaderDemo.java");
        // 装饰器
        MyLineNumberReader mylnr = new MyLineNumberReader(fr);

        String line = null;
        while (((line=mylnr.MyReadLine())!=null)) // 调用类中方法
        {
            System.out.println(mylnr.getLineNumber()+" - "+line);
        }
        mylnr.myClose();
    }
}

7 一个例子:使用字节流复制图片

关于字节流,字节流操作的对象是多媒体文件,例如视频、图片、歌曲文件,字节流有两个类:InputStream、OutputStream,下面实例演示如何复制一张图片,用到了一个暂时的数据容器buf

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyPicture  {
    public static void main(String[] args) throws IOException
    {
        FileInputStream fis = null;
        FileOutputStream fos = null;

        try
        {
            fis = new FileInputStream("PIG.jpg");// 需要复制文件
            fos = new FileOutputStream("PIG_copy.jpg");// 得到的文件
            byte[] buf = new byte[1024]; // 以1k为单位写入
            int len = 0;
            while ((len=fis.read(buf))!=-1) // 写入到缓存buf
            {
                fos.write(buf,0,len); // 将缓存内容写入文件,直到文件复制结束。
            }
        }
        catch (IOException e)
        {
            throw new RuntimeException("复制文件失败");
        }
        finally {
            try
            {
                if (fis!=null)
                    System.out.println("复制成功");
                    fis.close();

            }
            catch (IOException e)
            {

            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值