前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >IO(上)

IO(上)

作者头像
Carlos Ouyang
发布2019-08-19 17:03:38
4180
发布2019-08-19 17:03:38
举报
文章被收录于专栏:Java 学习日记Java 学习日记

1 输入流和输出流

输入流,数据从源数据源流入程序的过程称为输入流。可以理解为从源数据源读取数据到程序的过程。

输出流,数据从程序流出到目的地的过程称为输出流。可以理解为把数据从程序写入目的地的过程。

数据源一般指提供数据的原始媒介,一般常见有文件、数据库、云端、其他硬件等能提供数据的媒介。

2 流的分类

3 InputStream/OutputStream

InputStream 是所有字节输入流的抽象父类,提供了以下方法:

  • read() 读取一个字节
  • read(byte[] buf) 读取一定量的字节到缓冲区数组 buf中。

FileInputStream 文件字节输入流,是 InputStream 的一个子类,专门用于从文件中读取字节到程序内存中。

代码语言:javascript
复制
 1 //需求:从文件读取一个字节
 2 public static void main(String[] args) {
 3         File file = new File("d:\\javatest\\a.txt");
 4         
 5         // 【1】创建管道
 6         FileInputStream in = null;
 7         
 8         try {
 9             in = new FileInputStream(file);
10             
11             // 【2】从管道读取一个字节
12             /*
13             int t;
14             t = in.read();
15             t = in.read();
16             t = in.read();
17             t = in.read();
18             */
19             // System.out.println(t);
20             
21             // 循环读取一个字节
22             int t;
23             StringBuilder sb = new StringBuilder();
24             while( (t=in.read()) != -1 ) {
25                 sb.append((char)t);
26             }
27             System.out.println(sb.toString());    
28         } catch (FileNotFoundException e) {
29             e.printStackTrace();
30         } catch(IOException e) {
31             e.printStackTrace();
32         }
33         
34         // 【3】关闭流管道
35         try {
36             in.close();
37         } catch (IOException e) {
38             e.printStackTrace();
39         }
40 }
代码语言:javascript
复制
 1 //一次读取多个字节
 2 public static void main(String[] args) {
 3         File file = new File("d:\\javatest\\a.txt");
 4         
 5         // 【1】创建管道
 6         FileInputStream in = null;
 7         
 8         try {
 9             in = new FileInputStream(file);
10             
11             // 【2】从管道读取多个字节到缓冲区
12             /*
13             byte[] buf = new byte[5];
14             int len;
15             len = in.read(buf);
16             len = in.read(buf);
17             len = in.read(buf);
18             len = in.read(buf);
19             
20             for(byte b:buf) {
21                 System.out.print((char)b+"\t");
22             }
23             System.out.println(len);
24             */
25             
26             // 通过循环读取文件
27             byte[] buf = new byte[5];
28             int len;
29             StringBuilder sb = new StringBuilder();
30             while( (len=in.read(buf)) != -1 ) {
31                 // 读取的内容是原始二进制流,需要根据编码的字符集解码成对于字符
32                 String str = new String(buf,0,len);
33                 sb.append(str);
34             }
35             System.out.println(sb.toString());    
36         } catch (FileNotFoundException e) {
37             e.printStackTrace();
38         } catch(IOException e) {
39             e.printStackTrace();
40         }
41         
42         // 【3】关闭流管道
43         try {
44             in.close();
45         } catch (IOException e) {
46             e.printStackTrace();
47         }
48 }

OutputStream 是所有字节输出流的抽象父类,提供了以下方法

  • write() 写入一个字节
  • write(byte[] buf) 写入一定量的字节到输出流

FileOutputStream 文件字节输出流,专门用于从内存中写入字节到文件中。

代码语言:javascript
复制
 1 public static void main(String[] args) {
 2         File file = new File("d:\\javatest\\c.txt");
 3         
 4         FileOutputStream out = null;
 5         
 6         try {
 7             // 【1】创建输出流管道
 8             out = new FileOutputStream(file);
 9             
10             // 【2】写入数据到管道中
11             // 一次写入一个字节
12             /*
13             out.write(97);
14             out.write(98);
15             out.write(99);
16             */
17             
18             // 一次写入多个字节
19             String str = "hello world";
20             // gbk
21             /*
22             byte[] buf = str.getBytes();
23             out.write(buf);
24             */
25             
26             byte[] buf = str.getBytes("UTF-8");
27             out.write(buf);
28             
29             System.out.println("写入完成!");
30             
31         } catch (FileNotFoundException e) {
32             e.printStackTrace();
33         } catch (IOException e) {
34             e.printStackTrace();
35         }
36         
37         // 【3】关闭流
38         try {
39             out.close();
40         } catch (IOException e) {
41             e.printStackTrace();
42         }
43 }

注意:

  1. 字符串写入文件时一定会存在编码问题。
  2. 通过字节流写入文件时,向管道写入一个字节,该字节立即写入文件中。

InputStream/OutputStream 用于字节的读写。主要用于读写二进制文件(图片、音频、视频),较少用于读写文本型文件。对于文本型文件可以使用 Reader/Writer 类。

4 Reader/Writer

Reader 是字符输入流的抽象父类,提供了

  • read() 一次读取一个字符
  • read(char[] cbuf) 一次读取多个字符到字符缓冲区cbuf,返回长度表示读取的字符个数。

FileReader 文件字符输入流,专门用于读取默认字符编码文本性文件。

代码语言:javascript
复制
 1 //需求:一次读取一个字符/多个字符到cbuf
 2 public static void main(String[] args) throws IOException {
 3         
 4         File file = new File("d:\\javatest\\d.txt");
 5         
 6         FileReader reader = new FileReader(file);
 7         
 8         // 【1】一次读取一个字符
 9         /*
10         int c;
11         c = reader.read();
12         c = reader.read();
13         c = reader.read();
14         c = reader.read();
15         c = reader.read();
16         System.out.println((char)c);
17         */
18         
19         // 【2】一次读取多个字符到cbuf中
20         /*
21         char[] cbuf = new char[2];
22         int len;
23         len = reader.read(cbuf);
24         len = reader.read(cbuf);
25         len = reader.read(cbuf);
26         len = reader.read(cbuf);
27         System.out.println(Arrays.toString(cbuf));
28         System.out.println(len);
29         */
30         
31         char[] cbuf = new char[2];
32         int len;
33         StringBuilder sb = new StringBuilder();
34         while( (len=reader.read(cbuf)) != -1 ) {
35             sb.append(cbuf,0,len);
36         }
37         
38         System.out.println(sb);
39 }

Writer 是字符输出流的抽象父类,提供了

  • write()
  • write(char[] cbuf)
  • write(String str)

FileWriter 文件字符输出流,专门用于写入默认字符编码的文本性文件。为了提高效率,File-Writer内部存在一个字节缓冲区,用于对待写入的字符进行统一编码到字节缓冲区,一定要在关闭流之前,调用flush方法刷新缓冲区,才能完成写入。

代码语言:javascript
复制
 1 //需求:写入字符到文件中
 2 public static void main(String[] args) throws IOException {
 3         File file = new File("d:\\javatest\\f.txt");
 4         
 5         FileWriter writer = new FileWriter(file);
 6         
 7         // 【1】一次写入一个字符
 8         /*writer.write('中');
 9         writer.write('国');*/
10         
11         // 【2】一次写入多个字符
12         /*char[] cbuf = {'h','e','l','l','o','中','国'};
13         writer.write(cbuf);*/
14         
15         // 【3】一次写入一个字符串
16         String str = "hello你好";
17         writer.write(str);
18         
19         
20         // 刷新字节缓冲区
21         writer.flush();
22         
23         // 关闭流通道
24         writer.close();
25         
26         System.out.println("写入完成");
27 }

5 转换流

InputStreamReader继承于Reader,是字节流通向字符流的桥梁,可以把字节流按照指定编码 解码 成字符流。

OutputStreamWriter 继承于 Writer,是字符流通向字节流的桥梁,可以把字符流按照指定的编码 编码 成字节流。

  • 把一个字符串以utf8编码写入文件
代码语言:javascript
复制
 1 public class Test {
 2     public static void main(String[] args) throws IOException {
 3         
 4         
 5         String str = "hello中国";
 6         File file = new File("d:\\javatest\\g.txt");
 7         
 8         // 【1】创建管道
 9         FileOutputStream out = new FileOutputStream(file);
10         OutputStreamWriter writer = new OutputStreamWriter(out, "utf8");
11         
12         // 【2】写入管道
13         writer.write(str);
14         
15         // 【3】刷新缓冲区
16         writer.flush();
17         
18         // 【4】关闭管道
19         out.close();
20         writer.close();
21         
22         System.out.println("写入完成");
23     }
24 }
  • 读取utf8文件
代码语言:javascript
复制
 1 public class Test01 {
 2     public static void main(String[] args) throws IOException {
 3         
 4         File file = new File("d:\\javatest\\g.txt");
 5         
 6         // 【1】建立管道
 7         FileInputStream in = new FileInputStream(file);
 8         InputStreamReader reader = new InputStreamReader(in, "UTF-8");
 9         
10         char[] cbuf = new char[2];
11         int len;
12         
13         StringBuilder sb = new StringBuilder();
14         while( (len=reader.read(cbuf))!=-1 ) {
15             sb.append(cbuf, 0, len);
16         }
17         System.out.println(sb.toString());
18         
19     }
20 }

Windows 平台默认的 utf8 编码的文本性文件带有 BOM 标识,java 转换流写入的 utf8 文件不带 BOM 标识。所以用 java 读取手动创建的 utf8 文件会出现一点乱码(?hello中国,"?"是 BOM 标识导致的)。

6 BufferedReader/BufferedWriter

BufferedReader 继承于Reader,提供了

  • read()
  • read(char[] cbuf)
  • readLine() 用于读取一行文本,实现对文本的高效读取。

BufferedReader 初始化时需要一个 Reader,本质上 BufferedReader 在 Reader 的基础上增加 readLine() 的功能。

代码语言:javascript
复制
 1 //需求:读取一首诗
 2 public static void main(String[] args) throws IOException {
 3                 
 4         // 按行读取gbk文本性文件
 5         
 6         File file = new File("d:\\javatest\\i.txt");
 7         
 8         // 【1】创建管道
 9         FileReader reader = new FileReader(file);
10         BufferedReader br = new BufferedReader(reader);
11         
12         // 【2】读取一行
13         /*
14         String line =  br.readLine();
15         line =  br.readLine();
16         line =  br.readLine();
17         line =  br.readLine();
18         */
19         
20         String line;
21         while( (line=br.readLine()) != null) {
22             System.out.println(line);
23         }
24 }

BufferedWriter继承于Writer,提供了

  • write()
  • write(char[] cbuf)
  • write(String str)
  • newline() 写入一个行分隔符。
代码语言:javascript
复制
 1 //需求:以gbk编码写入一首诗到文件
 2 public static void main(String[] args) throws IOException {
 3         
 4         File file = new File("d:\\javatest\\j.txt");
 5         
 6         // 【1】创建gbk管道
 7         FileWriter writer = new FileWriter(file);
 8         BufferedWriter bw = new BufferedWriter(writer);
 9         
10         // 【2】写入一行
11         bw.write("窗前明月光,");
12         bw.newLine();
13         
14         bw.write("疑似地上霜。");
15         
16         // for win
17         // bw.write("\r\n");
18         
19         // for unix/linux/mac
20         // bw.write("\n");
21         
22         bw.write("举头望明月,");
23         bw.newLine();
24         
25         // 【3】flush
26         bw.flush();
27         
28         // 【4】关闭管道
29         bw.close();
30         writer.close();
31 }
代码语言:javascript
复制
 1 //需求:以utf8编码高效写入文件
 2 public static void main(String[] args) throws IOException {
 3         
 4         File file = new File("d:\\javatest\\j-utf8.txt");
 5         
 6         // 【1】创建utf8管道
 7         FileOutputStream out = new FileOutputStream(file);
 8         OutputStreamWriter writer = new OutputStreamWriter(out, "UTF-8");
 9         BufferedWriter bw = new BufferedWriter(writer);
10         
11         // 【2】写入一行
12         bw.write("窗前明月光,");
13         bw.newLine();
14         
15         bw.write("疑似地上霜。");
16         
17         // for win
18         bw.write("\r\n");
19         
20         // for unix/linux/mac
21         // bw.write("\n");
22         
23         bw.write("举头望明月,");
24         bw.newLine();
25         
26         // 【3】flush
27         bw.flush();
28         
29         // 【4】关闭管道
30         bw.close();
31         writer.close();
32 }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-05-06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 输入流和输出流
  • 2 流的分类
  • 3 InputStream/OutputStream
  • 4 Reader/Writer
  • 5 转换流
  • 6 BufferedReader/BufferedWriter
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档