数据流是指一组有顺序的,有起点和终点的字节集合。

最初的版本中,java.io 包中的流只有普通的字节流,即以 byte 为基本处理单位的流。字节流用来读写 8 位的数据,由于不会对数据做任何转换,因此可以用来处理二进制的数据。在后来的版本中,java.io 包中又加入了专门用于字符流处理的类,这个以 Reader 和 Writer 为基础派生的一系列的类。

另外,为了使对象的状态能够方便地永久保存下来,java.io 包中又提供了以字节流为基础的用于对象的永久化保存状态的机制,通过实现 ObjectInput 和 ObjectOutput 接口来完成。

InputStream 和 OutputStream 两个类都是抽象类,抽象类不能进行实例化。在实际应用中我们要用到一系列基本数据流类,都是他们的子类,在实现其父类方法的同时又都定义了其特有的功能。

输入数据流

输入数据流中提供的主要数据操作方法

int read():从输入流中读取一个字节的二进制数据

int read(byte[] b):将多个字节读到数组中,填满整个数组

int read(byte[] b, int off, int len):从输入流中读取长度为len的数据,从数组 b 中下标为 off 的位置开始放置读入的数据,读毕返回读取的字节数

以上三个方法中,所读取的数据都默认为字节类型。当输入流读取结束时,会得到 -1,以标志数据流的结束。第一个 read() 方法将读取的一个字节作为低位,形成一个 0~255 的 int 类型的数值返回

void close():关闭数据流

long skip(long l):跳过数据流中指定数量的字节不读取,返回值表示实际跳过的字节数

对于数据流中的字节的读取通常是按从头到尾顺序进行的,如果需要以反方向读取,则需要使用回推(Push Back)操作,支持回推操作的数据流中常用的方法如下

boolean markSupported():用于测试数据流是否支持回推操作,当一个数据流支持 mark() 和 reset() 方法时返回 true,否则返回 false

void mark(int markarea):用于标记数据流的当前位置,并划出一个缓冲区,其大小至少为指定参数的大小

void reset():将输入流重新定位到对此流最后调用 mark 方法时的位置

输出数据流

输出数据流中提供的主要数据操作方法

void write(int i):将字节 i 写入到数据流中,它只输出所读入参数的最低 8 位

void write(byte b[]):将数组 b[] 中的全部 b.length 个字节写入数据流

void write(byte b[], int off, int len):将数组 b[] 中从下标 off 开始的 len 个字节写入数据流。元素 b[off] 是此操作写入的第一个字节, b[off + len - 1] 是此操作写入的最后一个字节

void close():当结束对输出数据流的操作时应该将其关闭

void flush():刷新此输出流并强制写出所有缓冲的输出字节

基本字节数据流类

文件数据流

文件数据流包括 FileInputStream 和 FileOutputStream,这两个类用来进行文件的I/O处理,其数据源或数据终点都应当是文件。通过所提供的方法可以对本机上的文件进行操作,但是不支持方法 mark() 和 reset()

示例(1)

FileInputStream fis = new FileInputStream("myFile.txt");//同样可以使用 FileOutputStream 向文件中输出字节

FIleOutputStream out = new FileOutputStream("myFile.txt");

示例(2)

FIleOutputStream out = new FileOutputStream("myFile.txt");

out.wirte('H');

out.wirte(69);

out.wirte(76);

out.wirte('L');

out.wirte('O');

out.close();

FIleInputStream fis = new FileInputStream("myFile.txt");

while(fis.available() > 0){

System.out.print(fis.read()+ " ");

}

fis.close();

过滤器数据流(直接继承与FilterInputStream、FilterOutputStream)

缓冲区数据流

一个过滤器数据流在创建时与一个已经存在的数据流相连,这样在从这样的数据流中读取数据时,它提供的是对一个原始输入数据流的内容进行了特定处理的数据。缓冲区数据流有BufferedInputStream 和 BufferedOutinputStream,它们是在数据流上增加了一个缓冲区,都属于过滤器数据流。当读写数据时,数据以块为单位先进入缓冲区(块大小可以进行设置),其后的读写操作则作用于缓冲区。采用这个办法可以降低不同硬件设备之间速度的差异,提高I/O操作的效率

示例(使用默认缓冲区大小)

FileInputStream fis = new FileInputStream("myFile.txt");

InputStream is = newBufferedInputStream(fis);

FileOutputStream fos= new FileOutputStream("myFile.txt");

OutputStream is = new BufferedOutputStream(fos);

示例(自定义设置缓冲区大小)

FileInputStream fis = new FileInputStream("myFile.txt");

InputStream is = new BufferedInputStream(fis, 1024);

FileOutputStream fos= new FileOutputStream("myFile.txt");

OutputStream is = new BufferedOutputStream(fos, 1024);

一般在关闭一个缓冲区输出流之前,应先使用 flush() 方法,强制输出剩余数据,以确保缓冲区内的所有数据全部写入输出流

数据数据流

前面提到的数据流中处理数据都是指字节或字节数组,这是进行数据传输时系统默认的数据类型。但实际上所处理的数据并非只有这两种类型,遇到这种情况时就要应用一种专门的数据流来处理。DataInputStream 和 DataOutputStream 就是这样的两个过滤器数据流,它们允许通过数据流来读写 Java 基本类型

示例

DataInputStream dis = newDataInputStream(is);

DataOutputStream ous= new DataOutputStream(os);

常用方法

//DataInputStream 常用方法

bytereadByte()longreadLong()

doublue readDouble()booleanreadBoolean()

String readUTF()intreadInt()floatreadFloat()shortreadShort()charreadChar()//DataOutputStream 常用方法

void writeByte(intaByte)void writeLong(longaLong)void writeDouble(doubleaBouble)void writeBoolean(booleanaBool)voidwriteUTF(String aString)void writeInt(intaInt)void writeFloat(floataFloat)void writeShort(shortaShort)void rwriteChar(char aChar)

虽然这两个数据流定义了对字符串进行读写的方法,但是由于字符编码的原因,应该避免使用这些方法。Reader 和 Writer 重载了这两个方法,对字符进行操作时应当使用 Reader 和 Writer 两个系列类中的方法

对象流

能够输入/输出对象的流称为对象流。Java 通过 java.io 包中的 ObjectInputStream 和 ObjectOutputStream 两个类实现把对象写入文件数据流或从文件数据流中读出的功能

示例

//写对象数据流

Date date= newDate();

FileOutputStream fos= new FileOutputStream("date.ser");

ObjectOutputStream oos = newObjectOutputStream(fos);

oos.writeObject(date);

oos.close();//读对象数据流

Date date= null;

FileInputStream fis= new FileInputStream("date.ser");

ObjectInputStream ois = newObjectInputStream(fis);

date=(Date) ois.readObject(date);

ois.close();

System.out.println("Date serialized at " + date);

序列化

序列化的概念

能够记录自己的状态以便将来得到复原的能力,称为对象的持久性(Persistence)。一个对象时可持久的,意味着它可以把这个对象存入内存或者磁盘等介质中,也就是把对象存为某种永久存储类型。对象通过数值来描述自己的状态,记录对象也就是记录下这些数值。把对象转换为字节序列的过程称为对象的序列化,把字节序列恢复为对象的过程称为对象的反序列化。序列化的主要任务是写出对象实例变量的数值。序列化是一种用来处理对象流的机制,所谓的对象流也就是将对象的内容进行流化。序列化是为了解决在对对象流进行读写操作时所引发的问题

Serializable 接口中没有定义任何方法,只是作为一个标记来指示实现该接口的类可以进行序列化,只有实现 Serializable 接口的类才能被序列化。当一个类实现 Serializable 接口时,表明该类加入了对象序列化协议

序列化一个对象,必须与特定的对象输出/输入流联系起来,通过对象输出流/输入流将对象状态保存下来或者将对象状态恢复。通过 java.io 包中的 ObjectInputStream 和 ObjectOutputStream 两个类可以实现。writeObject() 和 readObject() 方法可以直接将对象保存到输出流中或者从输出流中读取一个对象

//序列化

public class Student implementsSerializable {intid;

String name;intage;

String department;public Student(int id, String name, intage, String department) {this.id =id;this.name =name;this.age =age;this.department =department;

}

}//对象的存储

Student stu= new Student(927103, "Li Ming", 16, "CSD");

FileOutputStream fo= new FileOutputStream("data.ser");

ObjectOutputStream so = newObjectOutputStream(fo);

so.writeObject(stu);

so.close();//对象的恢复

Student stu;

FileInputStream fi= new FileInputStream("data.ser");

ObjectInputStream si = newObjectInputStream(fi);

stu=(Student)si.readObject();

si.close();

System.out.println("ID:" + stu.id + ";name:" + stu.name);

对象结构表

序列化只能保存对象的非静态成员变量,而不能保存任何成员方法和静态成员变量,并且保存的只是变量的值,对于变量的任何修饰符都不能保存,访问权限(public, protected, private)对于数据域的序列化没有影响

有一些对象不具有可持久性,因为其数据的特性决定了它会经常变化,其状态只是瞬时的,这样的对象是无法保存起状态的,如 Thread 对象。对于这样的成员变量,必须用 transient 关键字标明,否则编译器将报错。任何用 transient 关键字标明的成员变量都不会被保存

序列化可能涉及将对象存放到磁盘上或者再网络上发送数据,这时会产生安全问题。对于一些保密的数据,为了保证安全,不应保存在永久介质中,应在这些变量前加上 transient 关键字

当数据变量是一个对象时,该对象的数据成员也可以被持久化。对象的数据结构或结构树,包括其子对象树在内,构成了这个对象的结构表

示例

public class Student implementsSerializable {public transientThread myThread;private transientString customerID;private inttotal;

}

基本字符流

从 JDK1.1 开始,java.io 包中加入了专门用于字符流处理的类,它们是以 Reader 和 Writer 为基础派生的一系列类。

一、读者(Reader)和写者(Writer)

同其他语言使用 ASCII 字符集不同,Java 使用 Unicode 字符集来表示和字符。ASCII 字符集以一个字节(8bit)表示一个字符,可以认为一个字符就是一个字节(byte)。但是 Java 使用的 Unicode 是一种大字符集,用两个字节(16bit)来表示一个字符,这时字节与字符就不再相同。为实现与其他程序语言及不同平台的交互,Java 提供一种新的数据流处理方案称作 Reader 和 Writer。在 java.io 包中有许多不同类对其进行支持,其中最重要的是 InputStreamReader 和 OutputStreamWriter 类。这两个类是字节流和 Reader 和 Writer 的接口,用来在字节流和字符流之间作为中介。

在英语国家中,字节编码采用 ISO8859_1 协议。ISO8859_1 是 Latin-1 编码系统映射到 ASCII 标准,能够在不同平台之间正确转换字符。

//构造映射到 ASCII 码的标准的 InputStreamReader 的方法

InputStreamReader ir= new InputStreamReader(System.in, "8859_1");//Reader 提供的方法

voidclose();void mark(intreadAheadLimit);booleanmarkSupported();intread();int read(char[] cbuf);int read(char[] cbuf, int off, intlen);booleanready();voidreset();long skip(longn);//Writer 提供的方法

voidclose();voidflush();void write(char[] cbuf);void write(char[] cbuf, int off, intlen);void write(intc);voidwrite(String str);void write(String str, int off, int len);

二、缓冲区读者和缓冲区写者

java.io 中提供流缓冲流 BufferedReader 和 BufferedWriter。其构造方法与 BufferedInputStream 和 BufferedOutputStream 类似。另外,除了 read() 和 write() 方法外,还提供了整行字符的处理方法

方法如下

public String readLine():BufferedReader 的方法,从输入流中读取一行字符,行结束标志为 '\n' 、'\r' 或者两者一起

public void newLine():BufferedWriter 的方法,向输出流中写入一个行结束标志

示例

FileInputStream fis = new FileInputStream("data.ser");

InputStreamReader dis= newInputStreamReader(fis);

BufferedReader reader= newBufferedReader(dis);//BufferedReader reader = new BufferedReader(new FileReader("data.ser"));

String s;while((s = reader.readLine()) != null) {

System.out.println("read:" +s);

}

dis.close();

当你写文件的时候,为了提高效率,写入的数据会先放入缓冲区,然后写入文件。因此有时候你需要主动调用 flush()方法

//FileWriter

FileWriter fw = new FileWriter("D:/Test.txt");

String s= "hello world";

fw.write(s,0, s.length());

fw.flush();//flush将缓冲区内容写入到问题件//OutputStreamWriter

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:/Test1.txt"));

osw.write(s,0, s.length());

osw.flush();//PrintWriter

PrintWriter pw = new PrintWriter(new OutputStreamWriter(newFileOutputStream("D:/Test2.txt")), true);//PrintWriter pw = new PrintWriter(new FileWriter("D:/Test2.txt"));

pw.println(s);//close AllWriter

fw.close();

osw.close();

pw.close();

文件拷贝

File file = new File("D:/Test.txt");

File dest= new File("D:/new.txt");try{

BufferedReader reader= new BufferedReader(newFileReader(file));

BufferedWriter writer= new BufferedWriter(new FileWriter(dest));

String line=reader.readLine();while(line!=null){

writer.write(line);

line=reader.readLine();

}

writer.flush();

reader.close();

writer.close();

}catch(FileNotFoundException e) {

e.printStackTrace();

}catch(IOException e) {

e.printStackTrace();

}

java io 输出流_Java IO 输入和输出流相关推荐

  1. 【java学习笔记-io流 文件读写和键盘读写】带缓存的输入/输出流和数据输入/输出流

    文章目录 字节流类 带缓存的输入/输出流 BufferedReader与BufferedWriter类 下面的例子程序演示了read()方法,从控制台读取字符直到用户键入"q": ...

  2. 学好JAVA保终身_JAVA IO 学习

    Java流的分类 1.输入/输出流 输入流:只能向其读数据,不能写. 输出流:只能向其写数据,不能读. 所谓的输入输出都是相对应用程序而言的. 2.字节流/字符流 单位不同,字节流操作8位,字符流操作 ...

  3. java 异步模型_Java IO编程全解(三)——伪异步IO编程

    为了解决同步阻塞I/O面临的一个链路需要一个线程处理的问题,后来有人对它的线程模型进行了优化,后端通过一个线程池来处理多个客户端的请求接入,形成客户端个数M:线程池最大线程数N的比例关系,其中M可以远 ...

  4. Java必备基础十六——输入与输出流相关类详细介绍

    坚持的第16篇. 鸡汤一下:真正能让你走远的,都是自律.积极和勤奋 文章目录 序言 一.什么是流 二.流的种类划分 1.按数据流的方向分:输入流.输出流 1.1 定义 1.2 层次结构 2.按处理数据 ...

  5. java关闭io流_Java IO流关闭问题的深入研究

    前言 前几天看了一篇文章(见参考文章),自己动手试了下,发现有些不一样结论,作博客记录下,本文主要研究两个问题: 1.包装流的close方法是否会自动关闭被包装的流? 答:会. 2.关闭流方法是否有顺 ...

  6. java 字节输出流_Java IO详解(三)------字节输入输出流

    那么这篇博客我们讲的是字节输入输出流:InputStream.OutputSteam(下图红色长方形框内),红色椭圆框内是其典型实现(FileInputSteam.FileOutStream) 1.字 ...

  7. java io字符输出流_JAVA IO 字符输入流与输出流总结说明

    目录 OutputStreamWriter 用于向本地文件中写入数据 InputStreamReader 用于读取本地文件中的字节数据 FileReader 用于读取本地文件中的字节数据 FileWr ...

  8. java 对象读写_java 对象输入输出流读写文件的操作实例

    java 对象输入输出流读写文件的操作实例 java 支持对对象的读写操作,所操作的对象必须实现Serializable接口. 实例代码: package vo; import java.io.Ser ...

  9. java输入文件内容_java Io流向指定文件输入内容

    package com.hp.io; import java.io.*; public class BufferedWriterTest{ public static void main(String ...

最新文章

  1. BCI competition IV 2b简介
  2. Ansible — Playbooks
  3. wp7使用Cocos2d-X for XNA制作一个塔防类游戏 (二)在游戏中加入地图和怪物。(上)
  4. IE8 chrome 中 table隔行换色解决办法
  5. 用python学编程_用Python学编程
  6. [公告]博客园新服务器照片
  7. 密码技术--椭圆曲线算法EDCSA数字签名及Go语言应用
  8. SpiderData 2019年2月22日 DApp数据排行榜
  9. 数据库性能(一):数据库索引原理解析
  10. mybatis学习(9):mybatis连接mysql数据库
  11. 笔记:数模美赛试题解析与研究
  12. EditPlus中文版
  13. C++11 使用智能指针封装 pimpl idom
  14. seo关键词排名优化的方法
  15. Span-Level Model for Relation Extraction论文学习
  16. html5显示状态灯,如何使用css3+html5来制作文字霓虹灯效果
  17. MySQL 主从架构在线热迁移MGR 方案
  18. GetLastError的返回值意思
  19. Unity3D 批量修改模型名称
  20. 学弟啊,你代码能不能不要写得这么烂?!--文末送书

热门文章

  1. mysql报错3534_win7下安装MYSQL报错:MYSQL 服务无法启动的3534问题
  2. 3号团队-团队任务4:每日例会(2018-12-3)
  3. oracle12c 新建表空间
  4. 嵌入式linux系统,给WIFI模块增加一个开关
  5. 【final】评价①
  6. 个人开源作品,即时通讯App支持文本、语音、图片聊天
  7. C++中的引用(257BinaryTreePath)
  8. jdbc链接数据库mysql
  9. Swift - 移除页面视图上的所有元素
  10. c# 泛型有什么作用?