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笔记 - 输入输出流的更多相关文章

  1. java:利用java的输入/输出流将一个文件的每一行+行号复制到一个新文件中去

    import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.Fi ...

  2. java学习笔记-输入输出流

    ================File类 =====================InputStream ==================OutputStream ============== ...

  3. java.IO输入输出流:过滤流:buffer流和data流

    java.io使用了适配器模式装饰模式等设计模式来解决字符流的套接和输入输出问题. 字节流只能一次处理一个字节,为了更方便的操作数据,便加入了套接流. 问题引入:缓冲流为什么比普通的文件字节流效率高? ...

  4. java 对象输入输出流

    对象的输入输出流的作用: 用于写入对象 的信息读取对象的信息. 对象的持久化. 比如:用户信息.              ObjectInputStream   : 对象输入流            ...

  5. 浅谈Java的输入输出流(转)

    Java语言的输入输出功能是十分强大而灵活的,美中不足的是看上去输入输出的代码并不是很简洁,因为你往往需要包装许多不同的对象.在Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:标准输 ...

  6. Java:输入输出流 java.io包的层次结构

    1.什么是IO Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列.Java的I/O流提供了读 ...

  7. JAVA基础-输入输出流

    一,File类:文件的创建和删除 1.File(String pathname):pathname是指路径名称.用法 File file = new File("d:/1.txt " ...

  8. Java基础—输入输出流

    流的概念 在Java中,流是从源到目的地的字节的有序序列.Java中有两种基本的流——输入流(InputStream)和输出流(OutputStream). 根据流相对于程序的另一个端点的不同,分为节 ...

  9. java的输入输出流(一)

    java中i/o流是java中核心的一部分,曾经学过.可是理解不够深入,渐渐的也就忘了,如今在从新学习下java的io处理,写下我学习的笔记.便于记忆,和总结归纳: 本文原创,转载请注明:http:/ ...

随机推荐

  1. 【转载】C# 开源库大全非常好

    原文地址:http://m.blog.csdn.net/woddle/article/details/37311877 C#开源大全 商业协作和项目管理平台-TeamLab 网络视频会议软件-VMuk ...

  2. android发编译

    普通的反编译http://blog.csdn.net/vipzjyno1/article/details/21039349/ 反编译os http://gikir.com/blog/?p=115 ht ...

  3. 取消设置透明状态栏,使 ContentView 内容不再覆盖状态栏

    取消设置透明状态栏,使 ContentView 内容不再覆盖状态栏,在MainActivity中添加以下代码: getWindow().clearFlags(WindowManager.LayoutP ...

  4. Redis 常用的数据结构

    String 字符串 set get 使用场景: 可以用来作为缓存使用(缓存更新策略和缓存雪崩如何处理) List lpop rpop lpush rpush 使用场景: set 无序集合 使用场景: ...

  5. 【转载】OpenCL实现矩阵相乘

    矩阵相乘其实就是前一个矩阵的每一行乘以后一个矩阵的每一列,然后将乘后的每一个数字相加,得到结果矩阵的指定位置的数值.具体算法回顾一下线性代数即可.但是这种行列相乘其实都是独立的,如果是CPU计算必须串 ...

  6. 概率dp的迭代方式小结——zoj3329,hdu4089,hdu4035

    在推导期望方程时我们常常会遇到dp[i]和其他项有关联,那么这时候我们就难以按某个顺序进行递推 即难以通过已经确定的项来求出新的项 即未知数的相互关系是循环的 但是我们又可以确定和dp[i]相关联的项 ...

  7. 将Form的AlphaBlend属性设置为True,之后调整Form的AlphaBlendValue属性,255为不透明,数字越小透明度越大~~~想显示文字用l

    将Form的AlphaBlend属性设置为True,之后调整Form的AlphaBlendValue属性,255为不透明,数字越小透明度越大~~~想显示文字用lable就行哈~~~直接在窗体上写字就行 ...

  8. System.Web.Mvc.HttpDeleteAttribute.cs

    ylbtech-System.Web.Mvc.HttpDeleteAttribute.cs 1.程序集 System.Web.Mvc, Version=5.2.3.0, Culture=neutral ...

  9. (34)C#异常

    一.异常的层次结构 二.异常格式 异常的一般格式 try { //可能会抛出异常的代码 } catch { //发现错误后会运行这里面的代码 } finally { //写不论是否出现异常都执行的代码 ...

  10. Maven父子工程配置文件详解

    项目骨架搭建成功之后. 因为父工程管理子工程.子工程相当于继承于子工程,所以子工程可以调用父工程里面的东西.那么就可以将jar包对应的配置文件书写到父工程的pom.xml文件中,注意:父工程的打包方式 ...