java--IO流之字节流、字符流

一、字节流:

IO异常的处理

代码实现:

 1 public class FileOutputStreamDemo3 {
 2     public static void main(String[] args) {
 3         File file = new File("c:\\file.txt");
 4         //定义FileOutputStream的引用
 5         FileOutputStream fos = null;
 6         try {
 7             //创建FileOutputStream对象
 8             fos = new FileOutputStream(file);
 9             //写出数据
10             fos.write("abcde".getBytes());
11         } catch (IOException e) {
12             System.out.println(e.toString() + "----");
13 throw new RuntimeException("文件写入失败,重试");
14 
15         } finally {
16             //一定要判断fos是否为null,只有不为null时,才可以关闭资源
17             if (fos != null) {
18                 try {
19                     fos.close();
20                 } catch (IOException e) {
21                     throw new RuntimeException("关闭资源失败");
22                 }
23             }
24         }
25     }
26 }

 

1、字节输出流OutputStream

 OutputStream此抽象类是表示输出字节流的所有类的超类。操作的数据都是字节,定义了输出字节流的基本共性功能方法。

输出流中定义都是写write方法,如下图:

OutputStream有很多子类,其中子类FileOutputStream可用来写入数据到文件。

FileOutputStream类,即文件输出流,是用于将数据写入 File的输出流。

关系

构造方法

 

代码实现:

 

public static void main(String[] args) throws IOException {
        //FileOutputStream的构造方法:如果文件存在,则覆盖,如果不存在,则创建
        // \r\n  换行
        FileOutputStream fos=new FileOutputStream("x:\\test\\bian.txt",true);//续写
        /*fos.write(49);
        fos.write(48);
        fos.write(48);*/
        /*byte[] bytes={-65,-66,-67,-68};
        fos.write(bytes,1,2);*/
        fos.write("xuezhiqian\r\n".getBytes()); //字符串转字节
        /*new String(bytes);*/    //字节转字符串
        fos.close();
    }

2、字节输入流InputStream 

常用方法:

FileInputStream类

 

构造方法:

FileInputStream类读取数据read方法

代码实现:

 1 public static void main(String[] args) throws IOException {
 2         FileInputStream fis=new FileInputStream("x:\\test\\test.txt");
 3         int len=0;
 4         while((len=fis.read())!=-1){
 5             System.out.println((char)len);//转字符
 6         }
 7         /*int a=fis.read();
 8         System.out.println((char)a);
 9         int b=fis.read();
10         System.out.println((char)b);
11         int c=fis.read();
12         System.out.println((char)c);
13         int d=fis.read();
14         System.out.println((char)d);
15         int e=fis.read();
16         System.out.println((char)e);
17         int f=fis.read();
18         System.out.println((char)f);*/
19         /*char ch=97;
20         System.out.println(ch);*/
21         fis.close();
22     }
23 }

 读取数据read(byte[])方法

代码实现:

 1 public class InputStreamDemo2 {
 2     public static void main(String[] args) throws IOException {
 3         FileInputStream fis=new FileInputStream("x:\\test\\test.txt");
 4         byte[] bytes=new byte[2];
 5         int len=0;
 6         while((len=fis.read(bytes))!=-1){
 7             System.out.println(new String(bytes,0,len));
 8         }
 9     /*    //第一次读
10         int len=fis.read(bytes);
11         System.out.println(len);
12         System.out.println(new String(bytes));
13         //第二次读
14         len=fis.read(bytes);
15         System.out.println(len);
16         System.out.println(new String(bytes));
17         //第三次读
18         len=fis.read(bytes);
19         System.out.println(len);
20         System.out.println(new String(bytes));
21         //第4次读
22         len=fis.read(bytes);
23         System.out.println(len);
24         System.out.println(new String(bytes));*/
25         fis.close();
26     }
27 
28 }

字节流复制文件

代码实现:

public class CopyDemo {
 2     public static void main(String[] args) throws IOException {
 3         long time1=System.currentTimeMillis();
 4         //1.明确数据源(要复制哪个文件)
 5         FileInputStream fis=new FileInputStream("C:\\Program Files\\java\\eclipse.zip");
 6         //2.明确目的地(要复制到哪个文件)
 7         FileOutputStream fos=new FileOutputStream("x:\\test\\d\\java.txt");
 8         //3.复制
 9         int len=0;
10         while((len=fis.read())!=-1){
11             fos.write(len);
12         }
13         long time2=System.currentTimeMillis();
14         System.out.println(time2-time1);
15         //4.释放资源
16         fis.close();
17         fos.close();
18     }
19 
20 }

3、缓冲字节流

①写入数据到流中,字节缓冲输出流 BufferedOutputStream

②读取流中的数据,字节缓冲输入流 BufferedInputStream 

它们的内部都包含了一个缓冲区,通过缓冲区读写,就可以提高了IO流的读写速度

字节缓冲输出流BufferedOutputStream

构造方法: 

public BufferedOutputStream(OutputStream out)创建一个新的缓冲输出流,以将数据写入指定的底层输出流。

代码实现:

1 //缓冲字节输出流
2     public static void method1() throws IOException{
3         FileOutputStream fos=new FileOutputStream("e:\\test\\haha",true);
4         BufferedOutputStream bos=new BufferedOutputStream(fos);
5         //bos.write(100);
6         bos.write("你好啊".getBytes());
7         bos.close();
8     }

字节缓冲输入流 BufferedInputStream

构造方法:

public BufferedInputStream(InputStream in)

代码实现:

 1 //缓冲字节输入流
 2     public static void method2() throws IOException{
 3         FileInputStream fis=new FileInputStream("e:\\test\\haha");
 4         BufferedInputStream bis=new BufferedInputStream(fis);
 5         int len=0;
 6         while((len=bis.read())!=-1){
 7             System.out.print((char)len);
 8         }
 9         bis.close();
10     }

对比字节流read(),字节流read(byte []),缓冲字节流read(),缓冲字节流read(byte [])它们的速度

 1 //字节流read()
 2     public static void method1() throws IOException{
 3         long time1=System.currentTimeMillis();
 4         FileInputStream fis=new FileInputStream("d:\\DW\\jdk\\javafx-src.zip");
 5         FileOutputStream fos=new FileOutputStream("e:\\test\\text\\haha1.zip");
 6         int len=0;
 7         while((len=fis.read())!=-1){
 8             fos.write(len);
 9         }
10         long time2=System.currentTimeMillis();
11         System.out.println(time2-time1);
12         fis.close();
13         fos.close();
14     }
15     //字节流read(byte [])
16     public static void method2() throws IOException{
17         long time1=System.currentTimeMillis();
18         FileInputStream fis=new FileInputStream("d:\\DW\\jdk\\javafx-src.zip");
19         FileOutputStream fos=new FileOutputStream("e:\\test\\text\\haha2.zip");
20         int len=0;
21         byte[] bytes=new byte[1024];
22         while((len=fis.read(bytes))!=-1){
23             fos.write(bytes, 0, len);
24         }
25         long time2=System.currentTimeMillis();
26         System.out.println(time2-time1);
27         fis.close();
28         fos.close();
29     }
30     //缓冲字节流read()
31     public static void method3() throws IOException{
32         long time1=System.currentTimeMillis();
33         FileInputStream fis=new FileInputStream("d:\\DW\\jdk\\javafx-src.zip");
34         BufferedInputStream bis=new BufferedInputStream(fis);
35         FileOutputStream fos=new FileOutputStream("e:\\test\\text\\haha3.zip");
36         BufferedOutputStream bos=new BufferedOutputStream(fos);
37         int len=0;
38         while((len=bis.read())!=-1){
39             bos.write(len);
40         }
41         long time2=System.currentTimeMillis();
42         System.out.println(time2-time1);
43         fis.close();
44         fos.close();
45     }
46     //缓冲字节流read(byte [])
47     public static void method4() throws IOException{
48         long time1=System.currentTimeMillis();
49         FileInputStream fis=new FileInputStream("d:\\DW\\jdk\\javafx-src.zip");
50         BufferedInputStream bis=new BufferedInputStream(fis);
51         FileOutputStream fos=new FileOutputStream("e:\\test\\text\\haha4.zip");
52         BufferedOutputStream bos=new BufferedOutputStream(fos);
53         int len=0;
54         byte[] bytes=new byte[1024];
55         while((len=bis.read(bytes))!=-1){
56             bos.write(bytes, 0, len);
57         }
58         long time2=System.currentTimeMillis();
59         System.out.println(time2-time1);
60         fis.close();
61         fos.close();
62     }

结果:

速度总结:(慢——>快)

字节流read()  <   缓冲字节流read()   <   字节流read(byte [])  <  缓冲字节流read(byte [])

二、字符流

字节流读取字符的问题

代码实现:

 

 1 public class CharStreamDemo {
 2     public static void main(String[] args) throws IOException {
 3         //给文件中写中文
 4         writeCNText();
 5         //读取文件中的中文
 6         readCNText();
 7     }  
 8     //读取中文
 9     public static void readCNText() throws IOException {
10         FileInputStream fis = new FileInputStream("c:\\cn.txt");
11         int ch = 0;
12         while((ch = fis.read())!=-1){
13             System.out.println(ch);
14         }
15     }
16     //写中文
17     public static void writeCNText() throws IOException {
18         FileOutputStream fos = new FileOutputStream("c:\\cn.txt");
19         fos.write("欢迎你".getBytes());
20         fos.close();
21     }
22 }

1.字符输入流Reader

基础方法:

FileReader类

代码实现:

public class ReaderDemo {

    public static void main(String[] args) throws IOException {
        //通过字符数组的方式读
        FileReader fr=new FileReader("x:\\test\\test.txt");
        int len=0;
        char[] ch=new char[1024];
        while((len=fr.read(ch))!=-1){
            System.out.println(new String(ch,0,len));
        }
        fr.close();
        //method1(fr);
    }
    public static void method1(FileReader fr) throws IOException{
        //通过一个字符一个字符的方法读
        int len=0;
        while((len=fr.read())!=-1){
            System.out.print((char)len);
        }
        fr.close();
    }

}

 2.字符输入流writer

 

基础方法:

 

 

 

    FileWriter类

 

 构造方法:

 

 

字符流复制文件代码实现:

 1 public class JpgCopy1 {
 2     //字符流复制文件
 3     public static void main(String[] args) throws IOException {
 4         //1.明确数据源
 5         FileReader fr=new FileReader("X:\\test\\img1.jpg");
 6         //2.明确目的地
 7         FileWriter fw=new FileWriter("x:\\test\\a\\img1.jpg");
 8         //3.复制
 9         int len=0;
10         char[] ch=new char[1024];
11         while((len=fr.read(ch))!=-1){
12             fw.write(ch, 0, len);
13         }
14         //4.释放资源
15         fr.close();
16         fw.close();
17     }
18 }

flush()和close()的区别

close是在关闭之前刷新一次

flush是一边存一边刷

代码实现:

1 public class WriterDemo {
2 public static void main(String[] args) throws IOException {
3   //写入中文字符 
4   FileWriter fw=new FileWriter("x:\\test\\test.txt"); 
5   fw.write("你好"); 
6   fw.flush();//可刷新多次 
7   //fw.close();//具有一次刷新功能 
8     }
9 }

3.字符缓冲输出流 BufferedWriter

将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入

方法:newLine() 根据当前的系统,写入一个换行符

 1 //缓冲字符输出流
 2 //bw.newLine();换行可以实现平台无关性
 3 //win 换行\r\n
 4 //linux 换行\n
 5 public static void method5() throws IOException{
 6     FileWriter fw=new FileWriter("E:\\test\\test.txt");
 7     BufferedWriter bw=new BufferedWriter(fw);
 8     bw.write("你好吗".toCharArray());//字符转字符数组
 9     bw.flush();
10     bw.write("我很好");
11     bw.newLine();//换行
12     bw.flush();
13     bw.newLine();
14     bw.write(100);
15     bw.close();
16 }

4.字符缓冲输入流 BufferedReader

从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

方法:readLine() 读取一个文本行包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null

代码实现:

public class BufferedReaderDemo {
    public static void main(String[] args) throws IOException {
        //1,创建流
        FileReader fr=new FileReader("file.txt")
        BufferedReader in = new BufferedReader(fr);
        //2,读数据
        //一次一个字符
        //一次一个字符数组
        //一次读取文本中一行的字符串内容
        String line = null;
        while( (line = in.readLine()) != null ){
            System.out.println(line);
        }
        //3,关闭流
        in.close();
    }
}                    

使用字符缓冲流完成文本文件的复制

 

public class CopyTextFile {
    public static void main(String[] args) throws IOException {
        //1,指定数据源, 是数据源中读数据,采用输入流
        BufferedReader in = new BufferedReader(new FileReader("file.txt"));
        //2,指定目的地,是把数据写入目的地,采用输出流
        BufferedWriter out = new BufferedWriter(new FileWriter("copyFile.txt"));
        //3,读数据
        String line = null;
        while ( (line = in.readLine()) != null ) {
            //4,写数据
            out.write(line);
            //写入换行符号
            out.newLine();
       out.flush();
        }
        //5,关闭流
        out.close();
        in.close();
    }
}

 

 

 

总结:流的操作规律

 

IO流中对象很多,解决问题(处理设备上的数据时)到底该用哪个对象呢?  

 

IO流进行了规律的总结(四个明确)

 

明确一:要操作的数据是数据源还是数据目的。

 

源:InputStream    Reader

 

目的:OutputStream Writer

 

先根据需求明确要读,还是要写。

 

明确二:要操作的数据是字节还是文本呢?

 

源:

 

字节:InputStream

 

文本:Reader

 

目的:

 

字节:OutputStream

 

文本:Writer

 

已经明确到了具体的体系上。

 

明确三:明确数据所在的具体设备。

 

源设备:

 

硬盘:文件  File开头。

 

内存:数组,字符串。

 

键盘:System.in;

 

网络:Socket

 

目的设备:

 

硬盘:文件  File开头。

 

内存:数组,字符串。

 

屏幕:System.out

 

网络:Socket

 

完全可以明确具体要使用哪个流对象。

明确四:是否需要额外功能呢?

 

额外功能:

 

转换吗?转换流。InputStreamReader OutputStreamWriter

 

高效吗?缓冲区对象。BufferedXXX

 

posted @ 2018-08-23 17:02  大树*  阅读(242)  评论(0编辑  收藏  举报