java基础-IO(Input Output)流(二)

字符流里面有自己的技术缓冲区,缓冲区的出现提高了对数据的读写效率。

字符流提供相应的缓冲区对象

BufferedWriter

BufferedRead

缓冲区的出现是为了提高流的操作效率而出现的

所以在创建缓冲区之前,必须要先有流对象

写入数据

class BufferedWriterDemo
{
    public static void main(String[] args) throws IOException
    {    
        //创建一个字符写入流对象
        FileWriter fw = new FileWriter("buf.txt");
        //为了挺高字符写入流效率,加入了缓冲技术
        //只要将流对象作为参数传递给 缓冲区的构造函数即可
        BufferedWriter bufw= new BufferedWriter("fw");
        
        bufw.writer("abcdef");
        
        //只要用到了缓冲区,就要刷新
        bufw.flush();
        // 其实关闭缓冲区,就是在关闭缓冲区的流对象
        bufw.close();    
    }
}

字符读取流缓冲区,该缓冲区提供了一个一次读一行的方法 readLine ,方便于对文本数据的获取

当返回null时,标识读到文件末尾。

class BufferedReaderDemo
{
    public static void main(String[] args) throws IOException 
    {
        //创建一个读取流对象和文件相关联
        FileReader fr = new FileReader("buf.txt");
        
        //为了提高效率,加入缓冲技术,将字符读取流对象作为参数传递给缓冲对象的构造函数
        BufferedReader bufr = new BufferedReader(fr);
                
            String line = null;
        while((line=bufr.readLine())!=null)
        {    
            System.out.println(line);
        }
        
    
    }

}    

通过缓冲区复制文本文件 .java文件

class CopyTextByBuf
{
        public void statci void(String[] args)
        {
        BufferedReader bufr = null;
        BufferedWriter bufw =null;

        try
           {
             bufr = new BufferedReader(new FileReader("BufferedWriter.java"));
             bufw = new BufferedWriter(new FileWriter("BufferedWriter_Copy.txt"));
                String line= null;
              while((line=bufr.readLine)!=null)
                     {
                        bufw.writer(line);
                        bufw.newLine();
                        bufw.flush();
                      }

           }catch(IOException e)
                    {    
                        throw new RuntimeException("读写失败");
                    }
            finally
            {
                try{
                    if(bufr!=null)
                        bufr.close();
                     }catch()
                        {
                        throw new RuntimeException("读取关闭失败");
                        }

                try{
                    if(bufw!=null)
                        bufw.close();
                     }catch()
                        {
                        throw new RuntimeException("写入关闭失败");
                        }

            }

            
        }

}

装饰设计模式,就是假如别人写了一个类,我去接手,不用动他写的类里的方法,我自己再写个装饰类,把他写的类作为构造函数的入参传进来就可以了,如果我写的有问题,可以直接注释掉,继续用他写的类里的方法。

当想要对已有的对象进行功能增强时

可以定义类,将已有对象传入,基于已有的功能,并提供加强功能

那么自定义的该类称为装饰类

装饰类通常会通过构造方法接收被装饰的对象

并基于被装饰的对象的功能,提供更强的功能

class Person
{
    public void chifan()
    {
    System.out.println("吃饭");
    
    }

}

class SuperPerson
{
    private Person p;
    SuperPerson(Person p)
    {
        this.p = p;
    }
    
    public void superChifan()
    {
        System.out.print("开胃酒");
        p.chifan();
        System.out.print("甜点");
        System.out.print("来一根");
    }
}

class PersonDemo
{
    public static void main(String[] args)   
        {
            Person p = new Person();
            
            SuperPerson sp = new SuperPerson();
            sp.superChifan();    
        }
}

 类LineNumberReader,带行号的

class LineNumberReaderDemo
{
    public static void main(String[] args) throws IOException
    {
        FileReader fr = new FileReader("PersonDemo.java");

        
        LineNumberReader lnr = new LineNumberReader(fr);

        String line =null;
        lnr.setLineNumber(100);
        
        while((line=lnr.readLine())!=null)
        {
                System.out.println(lnr.getLineNumber()+":"+line);
        }
        
        lnr.close();
    }

}

字符流,操作文本

FileReader

FileWriter

BufferedReader

BufferedWriter

字节流

操作图片,想要操作图片数据,这时候就要用到字节流,字节流,不用刷新方法,但是也得用关闭资源方法。

OutputStream 是代表写,凡是输出的都是写

InputStream 是读

class FileStream
{
    public static void main(String[] args)    
    {
        writerFile();    
    }    
    //用字节流写入文件
    public static void writerFile() throws IOException    
    {
            FileOutputStream fos = new FileOutputStream("fos.txt");
            
            fos.writer("abcdef".getBytes());        
            //不用刷新
            fos.close();
    }
    
    //用字节流读取文件第一种方式
    public static void readFile1() throws IOException
    {
            FileInputStream fis = new FileInputStream("fos.txt");
            
            int ch=0;
            
            while((ch=fis.read())!=-1)
            {
                   System.out.println((char)ch);
            }
            
            fis.close();
    }
    //用字节流读取文件第二种方式
    public static void readFile2() throws IOException
    {
        FileInputStream fis = new FileInputStream("fos.txt");
        
        byte[] buf = new byte[1024];
        int len= 0;
        
        while((len=fis.read(buf))!=-1)
        {    
                System.out.println( new String(buf,0,len));
        }
            fis.close();
    }

    
    //用字节流读取媒体文件第三种方式,字节流特有的,但是此方法如果 视频或者图片很多,可能会导 
    //致new的对象很大,内存溢出,jvm默认启动内存空间是64M,一般不用此方法
    
    public statci void readFile3() throws IOExcepiton
    {
        FileInputStream  fis = new FileInputStream("fos.txt"); 
        
        byte[] buf = new byte[fis.available()];//定义一个刚刚好缓冲区,不用循环了

        fis.read(buf);

        System.out.println(new String(buf));
        
        fis.close();       

    }
                


}

复制一个图片步骤

1、用字节流读取流对象和图片关联

2、用字节流写入流对象创建一个图片文件,用于存储获取到的图片数据

3、通过循环读写,完成数据的存储

4、关闭资源

字符流 只用来处理文字数据的,不能用来拷贝图片

class CopyPic
{
    pubic static void main(String[] args)
    {
       
        try
        {
         FileOutputStream fos = null;
         FileInputStream fis = null;
         byte[] buf = new byte[1024];
         int len =0;
           
         while((len=fis.read(buf)!=-1)
            {
               fos.writer(buf,0,len); 
            }
        }catch(IOException e)
        {
             throw new RuntimeException("复制图片异常");
        }
        finally
        {    
            try
            {
            if(fos!=null)
            {
                fos.close();
            }
            }catch(IOException e)
                    {
                     throw new RuntimeException("写入图片异常");
                    }
            try
            {
              if(fis!=null)
            {    
                fis.close();
            }
            }catch(IOException e)
                    {
                        throw new RuntimeException("读取图片异常");
                    }
            
        }
        
    }

}

字节流的缓冲区

class CopyMp3
{
    public static void main(String[] args)
    {    
        long start= System.currentTimeMillis();
        copy_1();
        long end=System.currentTimeMillis();
        System.out.println((end-start)+"毫秒");
    }
        
    public static void copy_1() throws IOException
    {
        BufferedInputStream bufis = new BufferedInputStream(new 
                                   FileInputStream("c:\\0.mp3"));
        BufferedOutputStream bufos =new BufferedOutputStream(new 
                                   FileOutStream("c:\\1.mp3"));
        
        int by= 0;
        while((by=bufis.read)!=-1)
        {
            bufos.writer(by);
        }
        
        bufis.close();
        bufos.close();
    }
}

读取键盘录入

class ReadIn
{
    
    public static void main(String[] args)
    {
        InputStream in = System.in;
        StringBuilder sb = new StringBuilder();
        
        while(true)
        {
            int ch =in.read();
            
            if(ch=="\r")
           
                continue;
            if(ch=="\n")
            {
                String s = sb.toString();
                if(s.equals(s))
                {
                    break;
                    System.out.println(s.toUpperCase);
                    sb.delete(0,sb.length);
                }
                
        
            }
            else
                {
                    sb.append((char)ch);
                }
            
        }
    }    
}

刚才的键盘录入一行数据并打印其大写,发现其实就是读一行数据的原理,也就是readLine方法

能不能直接用readLine方法来完成键盘录入的一行数据的读取呢

readLine方法是字符流BufferedReader类中的方法

而键盘录入的read方法是InputStream的方法

读取转换流

class TranStreamDemo
{
    public static void main(String[] args)
    {    
        //获取键盘录入对象
        InputStream in = System.in;
        //将字节流对象转成字符流对象,使用转化流
        InputStreamReader isr = new InputStreamReader(in);
        //为了提高效率,将字符串进行缓冲区技术高效操作,使用BufferedReader
        BufferedReader bufr = new BufferedReader(isr);
    
        String line = null;
        while((line=bufr.readLine())!=null)
        {
            if("over".equals(line))
            break;
            System.out.println(line.toUpperCase());
        }
        
        bufr.close();
     }
    
}

写入转换流

class TranStreamDemo
{
    public static void main(String[] args)
    {
            
        //键盘录入,就用这句  最常见写法,  把字节流转成字符流,在加入到缓冲区
        BufferedReader bufr = new BufferedReader (new InputStreamReader(System.in));


        //
        BufferedWriter bufw = new BufferedWriter(new OutStreamWriter(System.out));
    
        String line = null;

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

1、源:键盘录入

目的:控制台

如上面的

2、需求,想把键盘录入的数据存储到文件中

源:键盘

目的:文件

class TransStreamDemo2
{
    public static void main(String[] args)
    {
        //键盘输入
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

        //储存到文件里
        BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("out.txt") ));
    
        String line = null;
        
        while((line=bufr.readLine)!=null)
        {
            bufr.writer(line);
            bufr.newLine()
            bufr.flush();
            bufr.close();

        }
    }
}

3、需求,把想要将一个文件的数据打印在控制台中

源:文件

目的:控制台

clase TransStreamDemo3
{
    public static void main(String[] args)
    {
        BufferedReader bufr = new BufferedReader(new InputStreamReader(FileInputStream("copy.txt")));
          

        BufferedWtriter bufw = new BufferedWtriter(new OutputStreamWriter(System.out));
        
        String line = null;
        while((line=bufr.readLine)!=null)
        {
            bufr.writer(line);
            bufr.newLine();
            bufr.flush();
            bufr.close();

        }
    

    }


}

流操作的基本规律

通过两个明确来完成

1、明确源和目的

源:输入流,InputStream Reader

目的:输出流,OutpuStream Writer

2、操作的数据是否是纯文本

是纯文本 字符流

不是纯文本,字节流

3、当体系明确后,在明确要使用哪个具体的对象

通过设备来进行区分,源设备包括,内存,硬盘,键盘

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

举例,

1、将一个文本文件中数据存储到另一个文件中,复制文件

源:文件 InputStream  Reader,因为是源所以使用的是读取流

是不是操作文本文件,是, 这时就可以选择Reader

这样体系就明确了, 接下来,明确要使用该体系中的哪个对象

明确设备,硬盘上的一个文件,Reader体系中,可以操作文件的对象是FileReader

FileReader fr = new FileReader("a.txt");

是否需要提高效率,加入Reader体系中缓冲区,BufferedReader

BufferedReader bufr = new BufferReader(fr);

 

目的:文件

OutputStream Writer 

是纯文本, Writer 

明确设备,硬盘,一个文件,可以操作文件的对象,FileWriter

FileWriter fw = new FileWriter("b.txt");

BufferedWriter bufw = new BufferWriter();

 

2、需求,将键盘录入的数据保存到一个文件中

源:InputStream Reader 

是不是纯文本? 是Reader 

设备:键盘,对应的对象是System.in

为了操作键盘的文本数据方便,转成字符流按照字符串操作是最方便的

所以既然明确了Reader,那么就将System.in 转成Reader

用了Reader体系中的流转换,InputStreamReader

InputStreamReader isr = new InputStreamReader(System.in);

是否要提高效率,使用BufferedReader

BufferedReader bufr = new BufferedReader(isr);

 

目的:OutputStream Writer

是否是存文本, 是Writer

设备:硬盘,一个文件,使用对象 FileWriter 

FileWriter fw = new FileWriter("a.txt");

需要提高效率BufferedWriter();

BufferedWriter bufw = new BufferedWriter(fw);

class TransStreamDemo2
{
    public static void main(String[] args)
    {
        //键盘录入的写法
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
        
        //
        BufferedWriter bufw = new BufferedWriter(new OutpurStreamReader(new FileOutStream("d.txt")));
        
        String line = null;
        while((line=bufr.readLine())!=null)
        {
            if("over".equals(line))
                break;
            bufw.writer();
            bufw.newLine();
            bufw.flush();
            bufw.close();
        }
        
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NeilNiu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值