Java笔记 - 输入输出流
java.io包中定义了各式各样的“流(stream)” 类型(类或抽象类),通过标准的方法实现对于数据的输入/输出操作。
一、流类型分类
以从不同的角度对其进行分类:按数据流的方向不同,可以分为 输入流 和 输出流(相对于程序来说的);按处理数据单位不同,可以分为 字节流 和 字符流 ;按功能不同,可以分为 节点流 和 处理流,处理流需要套接在节点流之上使用。
1、节点流
节点流位可以从一个特定的数据源(节点)读写数据(如:文件、内存)。

常见的节点流类型如下:

2、处理流
处理流是 “连接/” 在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能,

常见的处理流类型如下:

二、流的继承架构
java.io包中所有的流类型,都分别继承以下四种抽象流类型。

1、InputStream
继承自InputStream的流都是 向程序中输入数据,且数 据的单位为字节(8bit)。
(1)InputStream的子类
下图中深色为节点流、浅色为处理流。

(2)InputStream的基本方法
1 //读取一个字节并以整数的形式返回(0 ~ 255)
2 //若果返回-1,表示已经到了输入流的末尾
3 int read() throws IOException;
4
5 //读取一系列字节并存储到一个数组buffer
6 //返回实际读取的字节数;若果返回-1,表示已经到了输入流的末尾
7 int read (byte [] buffer) throws IOException;
8
9 //从offset位置开始,读取length个字节,并存储到一个字节数组buffer
10 //返回实际读取的字节数;若果返回-1,表示已经到了输入流的末尾
11 int read (byte [] buffer,int offset,int length) throws IOException;
12
13 //关闭流释放内存资源
14 void close () throws IOException ;
15
16 //跳过n个字节不读,返回实际跳过的字节数
17 long skip(long n) throws IOException;
2、OutputStream
继承自OutputStream的流是用于从程序中输出数据,且数据的单位为字节(8bit)。
(1)OutputStream的子类
下图中深色为节点流、浅色为处理流。

(2)OutputStream的基本方法
1 //向输出流中写入一个字节数据,该字节数据为参数b的低8位
2 void write(iunt b) throws IOException;
3
4 //将一个字节类型的数组中的数据写入输出流
5 void write(byte [] b) throws IOException;
6
7 //将一个字节类型的数组中,从off位置开始的len个字节写入到输出流
8 int write (byte [] b,int off,int len) throws IOException;
9
10 //关闭流释放内存资源
11 void close () throws IOException ;
12
13 //将输入流中缓存的数据全部写入到目的地
14 long flush(long n) throws IOException;
3、Reader
继承自Reader的流都是向程序中输入数据,且数据的单位为字符(16bit)。
(1)Reader的子类
下图中深色为节点流、浅色为处理流。

(2)Reader的基本方法
1 //读取一个字符并以整数的形式返回(0 ~ 255)
2 //若果返回-1,表示已经到了输入流的末尾
3 int read() throws IOException;
4
5 //读取一系列字符并存储到一个数组buffer
6 //返回实际读取的字符数;若果返回-1,表示已经到了输入流的末尾
7 int read (char [] cbuf) throws IOException;
8
9 //从offset位置开始,读取length个字符,并存储到一个字符数组buffer
10 //返回实际读取的字符数;若果返回-1,表示已经到了输入流的末尾
11 int read (char [] cbuf,int offset,int length) throws IOException;
12
13 //关闭流释放内存资源
14 void close () throws IOException ;
15
16 //跳过n个字符不读,返回实际跳过的字符数
17 long skip(long n) throws IOException;
4、Writer
继承自Writer的流是用于从程序中输出数据,且数据的单位为字符(16bit)。
(1)Writer的子类
下图中深色为节点流、浅色为处理流。

(2)Writer的基本方法
1 //向输出流中写入一个字符数据,该字节数据为参数b的低16位
2 void write(int b) throws IOException;
3
4 //将一个字符类型的数组中的数据写入输出流
5 void write(char [] cbuf) throws IOException;
6
7 //将一个字符类型的数组中,从off位置开始的len个字节写入到输出流
8 int write (char [] cbuf,int off,int len) throws IOException;
9
10 //将一个字符串中的字符写入到输出流
11 void write(String str) throws IOException;
12
13 //将一个字符串从offset位置开始的length个字符写入输出流
14 void write (String str ,int offset,int length) throws IOException;
15
16 //关闭流释放内存资源
17 void close () throws IOException ;
18
19 //将输入流中缓存的数据全部写入到目的地
20 long flush(long n) throws IOException;
三、流的详细用法
1、文件流 类型
1 import java.io.*;
2 public class Main {
3 public static void main(String[] args) {
4 int b = 0;
5 FileReader in = null;//输入字符流,若采用FileinputStream则不能读取中文
6 FileWriter out = null;//输出字符流,若采用FileOutputStream则不能写入中文
7
8 try {
9 in = new FileReader("file.txt"); //若没有该文件,则抛出FileNotFoundException
10 out = new FileWriter("copy.txt"); //若没有该文件,则会自动创建copy.java
11 while((b=in.read())!=-1){
12 System.out.print((char)b); //必须进行类型转换,否则打印的是Unicode码
13 out.write(b);//以字节为单位,向输出流写入数据
14 }
15 } catch (FileNotFoundException e1) {
16 System.out.println("找不到指定文件"); System.exit(-1);
17 } catch (IOException e2) {
18 System.out.println("文件复制错误"); System.exit(-1);
19 }finally{
20 try {
21 in.close();
22 out.close();
23 } catch (IOException e) {
24 System.out.println("连接已关闭失败!");System.exit(-1);
25 }
26 }
27 System.out.println("文件已复制");
28 }
29 }
30
2、数据流 类型
DataInputStream 和DataOutputStream 属于处理流,提供了可以存取与机器无关的JAVA原始类型数据(如:long、double、UTF)等的方法,多用于进行网络数据传输。
(1)构造方法
DataInputStream (InputStream in)
DataOutputStream (OutputStream out)
(2)举例
1 import java.io.*;
2 public class Main {
3 public static void main(String[] args) {
4
5 ByteArrayOutputStream baos = new ByteArrayOutputStream(); //字节数组输出流
6 ByteArrayInputStream bais = null;//字节数组输入流
7
8 DataOutputStream dos = new DataOutputStream(baos);//输出流
9 DataInputStream dis = null;//输入流
10
11 try {
12 dos.writeDouble(Math.random());//向字节数组写入一个随机数
13 dos.writeBoolean(true);//向字节数组写入一个布尔变量
14
15 bais = new ByteArrayInputStream(baos.toByteArray());
16 dis = new DataInputStream(bais);
17
18 System.out.println(bais.available());//字符数组大小
19 System.out.println(dis.readDouble());//先写的先读
20 System.out.println(dis.readBoolean());
21
22 } catch (IOException e) {
23 e.printStackTrace();
24 }finally {
25 try {
26 dos.close();
27 dis.close();
28 } catch (IOException e) {
29 e.printStackTrace();
30 }
31 }
32 }
33 }
3、缓冲流 类型
缓冲流是 “套接” 在相应的节点流之上,对读取的数据提供缓冲的功能,提高读写效率,同时也增加了一些新的方法,如readLine阻塞式方法等。
(1)常用构造方法
1 BufferedReader(Reader in)
2 BufferedReader(Reader in,int sz) //sz为自定义缓冲大小
3
4 BufferedWriter(Writer out)
5 BufferedWriter(Writer out,int sz)
6
7 BufferedInputStream(InputStream out)
8 BufferedInputStream(InputStream out,int sz)
9
10 BufferedOutputStream(OutputStream out)
11 BufferedOutputStream(OutputStream out,int sz)
(2)使用readLine和write读写数据
BufferedReader提供了readLine方法用于读取一行字符串(以\r或\n分隔)、newLine用于写入一行分隔符、flush方法用于将先在内存中缓存的数据立刻写出。
1 import java.io.*;
2 public class Main {
3 public static void main(String[] args) {
4 String s = null;
5 BufferedReader br = null;//输入字符流,若采用BufferedInputStream则不能读取中文
6 BufferedWriter bw = null;//输入字符流,若采用BufferedOutputStream则不能写入中文
7 try {
8 br = new BufferedReader(new FileReader("file.txt"));
9 bw = new BufferedWriter(new FileWriter("copy.txt"));
10
11 while((s=br.readLine())!=null){
12 System.out.println(s);
13 bw.write(s);
14 bw.newLine();
15 }
16 bw.flush();
17
18 } catch (IOException e) {
19 e.printStackTrace();
20 }finally {
21 try {
22 br.close();
23 bw.close();
24 } catch (IOException e) {
25 e.printStackTrace();
26 }
27 }
28 }
29 }
(3)使用mark和reset方法
mark(int readlimit)方法标记当前位置,并保证在mark以后最多可以读取readlimit字节数据,mark标记仍有效。如果在mark后读取超过readlimit字节数据,mark标记就会失效,调用reset()方法会有异常。但实际上只要在mark标记后读取的数据没有超出缓冲区的大小,mark标记就不会失效,仍然能正确调用reset方法重置。 。
1 import java.io.*;
2 public class Main {
3 public static void main(String[] args) {
4 int c = 0;
5 String s = null;
6 BufferedReader br = null;
7
8 try {
9 br = new BufferedReader(new FileReader("file.txt"));
10
11 for(int i=0;i<=15 && (c=br.read())!=-1;i++){
12 if(c == 'd') br.mark(5);
13 System.out.print((char)c+" ");//包含了回车换行符
14 }
15 br.reset();
16
17 while((s=br.readLine())!=null){
18 System.out.println(s);
19 }
20
21 } catch (IOException e) {
22 e.printStackTrace();
23 }finally {
24 try {
25 br.close();
26 } catch (IOException e) {
27 e.printStackTrace();
28 }
29 }
30 }
31 }
4、转换流 类型
InputStreamReader和OutputStreamWriter用于字节数据转换到字符数据,转换流在构造时可以指定其编码集合。
1 import java.io.*;
2 public class Main {
3 public static void main(String args[]) {
4 BufferedReader istr = null;
5 OutputStreamWriter ostr = null;
6 String s = null;
7
8 try {
9 istr = new BufferedReader(
10 new InputStreamReader( new FileInputStream("file.txt")));
11 ostr = new OutputStreamWriter(
12 new FileOutputStream("copy.txt", true),"utf-8"); // ISO8859_1
13
14 ostr.write(ostr.getEncoding());
15 while((s=istr.readLine())!=null){
16 System.out.println(s);
17 ostr.write(s);
18 }
19 ostr.flush();
20
21 } catch (IOException e) {
22 e.printStackTrace();
23 }finally {
24 try {
25 istr.close();
26 ostr.close();
27 } catch (IOException e) {
28 // TODO Auto-generated catch block
29 e.printStackTrace();
30 }
31 }
32 }
33 }
5、Print流 类型
PrintWriter和PrintStream都属于输出流,处理数据的单位分别是字符和字节。PrintWriter和PrintStream提供了重载的print和println方法用于多种数据类型的输出 以及 在关闭连接之前可以自动flush的功能。另外,Print流的操作不会抛出异常,用户通过检测错误状态获取错误信息。
注:System.in和System.out默认是键盘输入输出。
(1)构造方法
PrintWriter( Writer out )
PrintWriter( Writer out , boolean autoFlush) //true表示以追加的方式写入
PrintWriter( OutputStream out )
PrintWriter( OutputStream out , boolean autoFlush)
PrintWriter( OutputStream out )
PrintWriter( OutputStream out ,,boolean autoFlush)
(2)举例
1 import java.util.*;
2 import java.io.*;
3 public class Main {
4 public static void main(String[] args) {
5 String s = null;
6 BufferedReader br = new BufferedReader( new InputStreamReader(System.in));
7
8 PrintWriter log1 = null;
9 PrintStream log2 = null;
10
11 try {
12 log1 = new PrintWriter(new FileWriter ("file.txt", true));
13 log2 = new PrintStream(new FileOutputStream ("file.txt", true));
14
15 if(log2 != null){
16 System.setOut(log2); //将System.out输出目的地设置成文件
17 }
18
19 while ((s = br.readLine())!=null) {
20 if(s.equalsIgnoreCase("exit")) break;
21
22 //在文件file中换行打印
23 log1.println(s.toUpperCase());
24 log2.println(s.toUpperCase());
25 System.out.println(s.toUpperCase());//默认立即flush
26 }
27 log1.println("==="+new Date()+"===");
28 log1.flush();//显式写出默认的flush方式,即在循环完成后一起flush
29 log2.flush();//也可写在循环中达到立即flush的效果
30
31 } catch (IOException e) {
32 e.printStackTrace();
33 }finally {
34 log1.close(); //不会抛出异常
35 log2.close();
36 }
37 }
38 }
6、Object流 类型
Object流可以直接将Object写入或写出,但Object类必须实现序列化接口。
(1)序列化接口
Serializable是序列化接口,标记类可以被序列化,无需重写方法,序列化过程由JRE控制。Externalizable是外部化接口,是Serializable的子接口,提供了readExternal和writeExternal方法,程序员可以重写这两个方法控制序列化过程。
(2)举例
1 import java.io.*;
2
3 public class Main {
4 public static void main(String args[]) throws Exception {
5 T t = new T();
6
7 //保存类
8 ObjectOutputStream oos = new ObjectOutputStream(
9 new FileOutputStream("file.dat"));
10 oos.writeObject(t);
11 oos.flush();
12 oos.close();
13
14 //读取类
15 ObjectInputStream ois = new ObjectInputStream(
16 new FileInputStream("file.dat"));
17 T tReaded = (T)ois.readObject();
18 System.out.println(tReaded.i + " " + tReaded.j + " " +
19 tReaded.d + " " + tReaded.k);
20
21 }
22 }
23
24 class T implements Serializable
25 {
26 int i = 10;
27 int j = 9;
28 double d = 2.3;
29 transient int k = 15;//transient修饰的成员变量在序列化时不予考虑,显示默认值0
30 }
7、管道 类型
Java笔记 - 输入输出流的更多相关文章
- java:利用java的输入/输出流将一个文件的每一行+行号复制到一个新文件中去
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.Fi ...
- java学习笔记-输入输出流
================File类 =====================InputStream ==================OutputStream ============== ...
- java.IO输入输出流:过滤流:buffer流和data流
java.io使用了适配器模式装饰模式等设计模式来解决字符流的套接和输入输出问题. 字节流只能一次处理一个字节,为了更方便的操作数据,便加入了套接流. 问题引入:缓冲流为什么比普通的文件字节流效率高? ...
- java 对象输入输出流
对象的输入输出流的作用: 用于写入对象 的信息读取对象的信息. 对象的持久化. 比如:用户信息. ObjectInputStream : 对象输入流 ...
- 浅谈Java的输入输出流(转)
Java语言的输入输出功能是十分强大而灵活的,美中不足的是看上去输入输出的代码并不是很简洁,因为你往往需要包装许多不同的对象.在Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:标准输 ...
- Java:输入输出流 java.io包的层次结构
1.什么是IO Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列.Java的I/O流提供了读 ...
- JAVA基础-输入输出流
一,File类:文件的创建和删除 1.File(String pathname):pathname是指路径名称.用法 File file = new File("d:/1.txt " ...
- Java基础—输入输出流
流的概念 在Java中,流是从源到目的地的字节的有序序列.Java中有两种基本的流——输入流(InputStream)和输出流(OutputStream). 根据流相对于程序的另一个端点的不同,分为节 ...
- java的输入输出流(一)
java中i/o流是java中核心的一部分,曾经学过.可是理解不够深入,渐渐的也就忘了,如今在从新学习下java的io处理,写下我学习的笔记.便于记忆,和总结归纳: 本文原创,转载请注明:http:/ ...
随机推荐
- 9-MySQL高级-主从同步时Slave_IO_Running:Connecting ; Slave_SQL_Running:Yes的情况故障排除
推荐!! 各种情况都考虑在内,条理清楚!! https://blog.csdn.net/mbytes/article/details/86711508
- 4-MySQL高级-事务-提交(3)
提交 为了演示效果,需要打开两个终端窗口,使用同一个数据库,操作同一张表 step1:连接 终端1:查询商品分类信息 select * from goods_cates; step2:增加数据 终端2 ...
- NFS服务器简易安装
1.服务端 创建挂载目录 # mkdir /data/nfs 安装NFS软件 # yum install nfs-utils -y 添加配置信息 # vim /etc/exports /data/nf ...
- 【笔记篇】(理论向)快速傅里叶变换(FFT)学习笔记w
现在真是一碰电脑就很颓废啊... 于是早晨把电脑锁上然后在旁边啃了一节课多的算导, 把FFT的基本原理整明白了.. 但是我并不觉得自己能讲明白... Fast Fourier Transformati ...
- 从别人git下载项目下来然后运行
1点击clone or download 2.自由选择 3.拉到你想放的位置,我是放到桌面上的 4. cmd 打开,进入你 的下载到桌面的项目 5. # install dependencies n ...
- U Must Know The .Net --7
关键字 1 new 创建对象/调用构造函数 隐藏基类成员 new()约束,表明泛型类声明中的任何参数都必须有公共无参构造函数 new 实现多态 1.1 new class:分配内存,调用构造函数实例化 ...
- 校园商铺-2Logback配置与使用-3验证配置
1. 验证logback配置 1.1. 启动tomcat,得到CATALINA_BASE地址: 1.2 访问接口,查看日志 浏览器打开http://localhost:18080/o2o/supera ...
- BZOJ 1398: Vijos1382寻找主人 Necklace(最小表示法)
传送门 解题思路 最小表示法.首先对于判断是不是循环同构的串,直接扫一遍用哈希判即可.然后要输出字典序最小的就要用到最小表示法,首先可以把串复制一遍,这样的话就可以把串变成静态操作.如果对于两个位置\ ...
- 使用WebStorm上传本地项目到GitHub和GitLab
在使用 WebStorm 上传本地项目到 GitHub 之前,先要做一些相关配置. 首先打开 WebStorm ,依次点击File -> Settings… 打开系统设置面板,在上面搜索 git ...
- csdn自动生成目录索引、插入代码片快捷键
文章目录 自动生成目录索引 插入代码片 自动生成目录索引 文章开头加入 @[TOC](目录描述) 目录描述可不写 插入代码片 cmd/ctrl + shift + k