Java标准I/O知识体系图:

1、I/O是什么?

I/O 是Input/Output(输入、输出)的简称,输入流可以理解为向内存输入,输出流是从内存输出。

2、流

流是一个连续的数据流,可以从流中读取数据,也可以往流中写数据。流与数据源,或数据源流向的媒介相关联。

在Java IO流中,流可以是字节流,也可以是字符流。

3、Java I/O 用途与对应的流一览

注:粗体为节点流。蓝色为转换流(字节流转为字符流)。

4、流的处理

流分节点流和处理流两种。

节点流:可以从或向一个特定的地方(节点)读写数据。如FileInputStream、FileReader。

处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader.处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接

5、文件访问

(1)读取文件

如果你需要在不同端使用读取文件,你可以根据你要读的文件是二进制文件还是文本文件,或者根据你要处理的数据是准备采取字节方式还是字符方式,决定使用 FileInputStream 或者 FileReader。两者支持你从文件开头开始到文件结尾读取一个字节或者字符,也可以将读取的多个字节或字符,写入到内存的字节数组或字符数组。

单字节读取文件示例:

public static void readFileAsByte() throws IOException {
String filepath = "file.bin";
java.io.InputStream is = null;
try {
is = new FileInputStream(filepath);
int data = -1;
while ((data = is.read()) != -1) {// -1 表示读取到达文件结尾
//操作数据
System.out.print((byte)data + " ");
}
} finally {
if (is != null) {
is.close();// 关闭流
}
}
}

字节数组读取文件示例:

public static void readFileAsByteArray() throws IOException {
String filepath = "file.bin";
java.io.InputStream is = null;
try {
is = new BufferedInputStream(new FileInputStream(filepath));// 组装BufferedInputStream流,加入缓冲能力
byte[] data = new byte[256];
int len = -1;
while ((len = is.read(data)) != -1) {// -1 表示读取到达文件结尾
//操作数据
for (int i = 0; i < len; i++) {
System.out.print(data[i] + " ");
}
}
} finally {
if (is != null) {
is.close();// 关闭流
}
}
}

  单字符读取文件示例:

public static void readFileAsChar() throws IOException {
String filepath = "file.txt";
java.io.Reader r = null;
try {
r = new FileReader(filepath);
int data = -1;
while ((data = r.read()) != -1) {// -1 表示读取到达文件结尾
//操作数据
System.out.print((char) data);
}
} finally {
if (r != null) {
r.close();// 关闭流
}
}
}

  字符数组读取文件示例:

public static void readFileAsCharArray() throws IOException {
String filepath = "file.txt";
java.io.Reader r = null;
try {
r = new BufferedReader(new FileReader(filepath));// 组装BufferedReader流,加入缓冲能力
char[] data = new char[256];
int len = -1;
while ((len = r.read(data)) != -1) {// -1 表示读取到达文件结尾
//操作数据
for (int i = 0; i < len; i++) {
System.out.print(data[i]);
}
}
} finally {
if (r != null) {
r.close();// 关闭流
}
}
}

(2)写入文件

与读取文件类似:

如果你需要在不同端使用写入文件,你可以根据你要写的文件是二进制文件还是文本文件,或者根据你要处理的数据是准备采取字节方式还是字符方式,决定使用 FileOutputStream 或者 FileWriter。两者支持你可以一次写入一个字节或者字符到文件中,也可以直接写入一个字节数组或者字符数据。数据按照写入的顺序存储在文件当中。

单字节写入文件示例:

public static void writeFileAsByte() throws IOException {
String filepath = "file.bin";
java.io.OutputStream os = null;
try {
os = new FileOutputStream(filepath);
os.write('1');
os.write('2');
os.write('3');
os.write('4');
os.flush();// 把缓冲区内的数据刷新到磁盘 } finally {
if (os != null) {
os.close();// 关闭流
}
}
}

  字节数组写入文件示例:

		String filepath = "file.bin";
java.io.OutputStream os = null;
try {
os = new BufferedOutputStream(new FileOutputStream(filepath));
// 模拟
byte[] data = new byte[256];
new Random().nextBytes(data); os.write(data);
os.flush();// 把缓冲区内的数据刷新到磁盘
} finally {
if (os != null) {
os.close();// 关闭流
}
}
}

  单字符写入文件示例:

public static void writeFileAsChar() throws IOException {
String filepath = "file.txt";
java.io.Writer w = null;
try {
w = new FileWriter(filepath);
w.write('1');
w.write('2');
w.write('3');
w.write('4');
w.flush();// 把缓冲区内的数据刷新到磁盘 } finally {
if (w != null) {
w.close();// 关闭流
}
}
}

  字符数组写入文件示例:

public static void writeFileAsCharArray() throws IOException {
String filepath = "file.txt";
java.io.Writer w = null;
try {
w = new BufferedWriter(new FileWriter(filepath));// 组装BufferedWriter流,加入缓冲能力
// 模拟
char[] data = new char[256];
String f = "0123456789abcdefghijklmnopqrstuvwxyz";
Random rd = new Random();
for (int i = 0; i < data.length; i++) {
data[i] = f.charAt(rd.nextInt(f.length()));
}
w.write(data);
w.flush();// 把缓冲区内的数据刷新到磁盘
} finally {
if (w != null) {
w.close();// 关闭流
}
}
} 

(3)随机访问文件

如果你需要不按特定的存取顺序,随意读取或者写入文件,可以考虑RandomAccessFile。

void seek(long pos)   设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。

简单示例:

public static void main(String[] args) throws IOException {
RandomAccessFile file = null;
try {
file = new java.io.RandomAccessFile("file.bin", "rw");
file.seek(0); file.writeChar('1');
file.seek(0);
System.out.println(file.readChar()); /**
* 读取
*/
int data = -1;
while ((data = file.read()) != -1) {// -1 表示读取到达文件结尾
//操作数据
System.out.print((byte)data + " ");
} } finally {
if (file != null) {
file.close();// 关闭流
}
}
}

 6、管道(线程内存)

管道为同一JVM中运行的线程提供基于内存的通信机制。但是你不能利用管道在不同的JVM中的线程间通信。

在概念上,Java的管道不同于Unix/Linux系统中的管道。在Unix/Linux中,运行在不同地址空间的两个进程可以通过管道通信。在Java中,通信的双方应该是运行在同一进程中的不同线程。当然除了管道之外,一个JVM中不同线程之间还有许多通信的方式。实际上,线程在大多数情况下会传递完整的对象信息而非原始的字节数据。但是,如果你需要在线程之间传递字节数据,Java IO的管道是一个不错的选择。

当使用两个相关联的管道流时,务必将它们分配给不同的线程。read()方法和write()方法调用时会导致流阻塞,这意味着如果你尝试在一个线程中同时进行读和写,可能会导致线程死锁。

简单示例:

static class Input implements Runnable {
private final PipedInputStream inputStream = new PipedInputStream();
public Input() {
}
public PipedInputStream getInputStream() {
return inputStream;
}
@Override
public void run() {
try {
byte[] buf = new byte[1024];
int len = -1;
System.out.println("管道读取准备。");
StringBuffer result = new StringBuffer();
while ((len = inputStream.read(buf)) > 0) {
//System.out.println(new String(buf, 0, len));
result.append(new String(buf, 0, len));
}
System.out.println("管道读取结果:" + result.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null)
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
static class Output implements Runnable {
private final PipedOutputStream outputStream = new PipedOutputStream();
public Output() {
}
public PipedOutputStream getOutputStream() {
return outputStream;
}
@Override
public void run() {
try {
System.out.println("管道写出准备。");
StringBuilder sb = new StringBuilder();
// 模拟 通过for循环写入2050个字节
for (int i = 0; i < 201; i++) {
sb.append("0123456789");
if (i > 0 && (i % 10 == 0)) {
sb.append("\r\n");
}
}
String str = sb.toString();
outputStream.write(str.getBytes());
System.out.println("管道写出完成。");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (outputStream != null)
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws IOException {
Input input = new Input();
Output output = new Output();
/**
* 将“管道输入流”和“管道输出流”关联起来。
*/
//input.getInputStream().connect(output.getOutputStream());// 与下面一行等价
output.getOutputStream().connect(input.getInputStream());
new Thread(input).start();
new Thread(output).start();
}

7、序列化与ObjectInputStream、ObjectOutputStream

使用ObjectInputStream、ObjectOutputStream读取或写入对象,首先该对象必须实现Serializable接口,使得能够序列化和反序列化。

简单示例:

@SuppressWarnings("unused")
public static void main(String[] args) throws IOException {
class A implements java.io.Serializable {
private static final long serialVersionUID = -9115696482036699559L;
private int i = 1;
private float f = 3;
private String s = "风策信";
public A() {
super();
}
public A(int i, float f, String s) {
super();
this.i = i;
this.f = f;
this.s = s;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("A [i=").append(i).append(", f=").append(f).append(", s=").append(s).append("]");
return builder.toString();
}
}
class B implements java.io.Serializable {
private static final long serialVersionUID = 6124575321340728225L;
private long i = 2;
private double f = 4;
private String str = "风策信";
public B() {
super();
}
public B(long i, double f, String str) {
super();
this.i = i;
this.f = f;
this.str = str;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("B [i=").append(i).append(", f=").append(f).append(", str=").append(str).append("]");
return builder.toString();
}
}
A a = new A(1, 3, "a");
B b = new B(2, 4, "b");
//System.out.println(a);
//System.out.println(b);
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("object.data.bin"));
oos.writeObject(a);
oos.writeObject(b);
oos.flush();// 把缓冲区内的数据刷新到磁盘
} finally {
if (oos != null)
oos.close();
}
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("object.data.bin"));
A a1 = (A) ois.readObject();
B b1 = (B) ois.readObject();
System.out.println(a1);
System.out.println(b1);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (ois != null)
ois.close();
}
}

  

Java 标准 IO 流编程一览笔录( 上 )的更多相关文章

  1. Java 标准 IO 流编程一览笔录( 下 )

    8.回推流:PushbackInputStream与PushbackReader PushbackInputStream/PushbackReader 用于解析InputStream/Reader内的 ...

  2. Java标准I/O流编程一览笔录

    I/O是什么 I/O 是Input/Output(输入.输出)的简称,输入流可以理解为向内存输入,输出流是从内存输出. 流 流是一个连续的数据流,可以从流中读取数据,也可以往流中写数据.流与数据源,或 ...

  3. Java之IO流学习总结【上】

    一.什么是流? 流就是字节序列的抽象概念,能被连续读取数据的数据源和能被连续写入数据的接收端就是流,流机制是Java及C++中的一个重要机制,通过流我们可以自由地控制文件.内存.IO设备等数据的流向. ...

  4. [JAVA]标准IO流操作

    import java.io.*; /** * @Description: * @projectName:JavaTest * @see:PACKAGE_NAME * @author:郑晓龙 * @c ...

  5. Java 多线程并发编程一览笔录

    Java 多线程并发编程一览笔录 知识体系图: 1.线程是什么? 线程是进程中独立运行的子任务. 2.创建线程的方式 方式一:将类声明为 Thread 的子类.该子类应重写 Thread 类的 run ...

  6. Java的IO流以及输入流与输出流的异同

    一:流的基本概念:           Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列.J ...

  7. java的IO流

    java的IO流继承四大抽象类分别是字节流 inputStream outputStream与字符流 read write.怎么理解记忆很重要. 直接连接读写对象的是结点流,例如对文件读取字节类的名字 ...

  8. Java基础——IO流

    今天刚刚看完java的io流操作,把主要的脉络看了一遍,不能保证以后使用时都能得心应手,但是最起码用到时知道有这么一个功能可以实现,下面对学习进行一下简单的总结: IO流主要用于硬板.内存.键盘等处理 ...

  9. Java中IO流的总结

    有关Java中IO流总结图 流分类 按方向分 输入流 输出流 按单位分 字节流 字符流 按功能分 节点流 处理流(过滤流) 其他 所有的流继承与这四类流:InputSteam.OutputStream ...

随机推荐

  1. Java组合模式(思维导图)

    图1 组合模式[点击查看图片] 1,以公司职员为例的结构 package com.cnblogs.mufasa.demo3; import java.util.ArrayList; import ja ...

  2. IOC+EF+Core搭建项目框架(三)

    /// <summary> /// 表示类别映射配置 /// </summary> public partial class sys_UserMap : NopEntityTy ...

  3. 1.DOS常用命令

    d:+ 回车:盘符切换,进入D:盘 dir(directory):列出当前目录下的文件及文件夹md(make director):创建目录rd(remove director):删除目录(不能删除非空 ...

  4. SIP 3pcc

    3PCC全称Third Party Call Control,中文即第三方电话呼叫控制,指的是由第三方控制者在另外两者之间建立一个会话,由控制者负责会话双方的媒体协商.3PCC是一种非常灵活的会话控制 ...

  5. Mysql与java对应的类型表

    1. 概述 在使用Java JDBC时,你是否有过这样的疑问:MySQL里的数据类型到底该选择哪种Java类型与之对应?本篇将为你揭开这个答案. 2. 类型映射  java.sql.Types定义了常 ...

  6. linux环境下安装python3的方法(转)

    Linux 安装python3.7.0   我这里使用的时centos7-mini,centos系统本身默认安装有python2.x,版本x根据不同版本系统有所不同,可通过 python --V 或 ...

  7. 7.使用EXPLAIN 来分析SQL和表结构_2

    possible_keys    ------   显示可能应用在这张表的索引,一个或多个 查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被实际查询使用 key   ------   实际使 ...

  8. Spring cloud实战——服务提供者

    目录讲解: 一.服务提供者与服务消费者的概念 二.编写一个服务提供者的测试类(code) 1.1. 使用微服务构建的是分布式系统,微服务之间通过网络进行通信.我们使用微服务提供者与服务消费者来描述微服 ...

  9. Dart运算符与语句格式

    算术运算符 + 加 - 减 * 乘 / 除 ~/ 取整 % 取余 关系运算符 == 是否等于 != 是否不等于 > 是否大于 < 是否小于 >= 是否大于等于 <= 是否小于等 ...

  10. 03.Zabbix应用服务监控

    一.Zabbix监控Nginx 1.1 实验环境 服务器系统 角色 IP CentOS 7.4 x86_64 Zabbix-Server 192.168.90.10 CentOS 7.4 x86_64 ...