Java把不同类型的输入、输出,这些输入输出有些是在屏幕上、有些是在电脑文件上, 都抽象为流(Stream)
按流的方向,分为输入流与输出流,注意这里的输出输出是相对于程序而言的,如:如对于一个Java程序创建了一个输入流(Input),此时应该是进行读取操作将数据读到程序中。
流既然是用来进行输入输出的,那么在所有的流中可以按每次输入输出的量分成两类流:字节流、字符流。顾名思义字节流每次操作为一个一个字节、字符流则每次读取一个一个字符。
额外的,在字符流中对于一个字符,不同编码方式他也有不同的表现形式,比如汉字,到底是这些字符采用UTF-8(多个字节),还是国标码(2个字节),不同编码对应不同的字节数。所以使用字符流时需要额外指定编码方式。
分成四个超类(很重要):
  字节流 字符流
输入流 InputStream Reader
输出流 OutputStream Writer
InputStream类
    read(),逐字节地以二进制的原始方式读取数据
  • public int read();        读入一个字节,-1表示无
  • public int read(byte b[]);            返回读入的字节数
  • public int read(byte[] b, int off, int len);
 
OutputStream类
  • write()方法,它的功能是将字节写入流中
  • public void write (int b);// 将参数b的低位字节写入到输出流
  • public void write (byte b[]);// 将字节数组b[]中的全部字节顺序写入到输出流
  • public void write(byte[] b, int off, int len);// 将字节数组b[]中从off开始的len个字节写入到流中
Output的另外两个方法是flush()及close()。
  • public void flush (); 刷新缓存,实际写入到文件、网络
  • public void close(); 关闭流
 
Reader类
与InputStream类相似,都是输入流,但差别在于Reader类读取的是字符(char),而不是字节。
Reader的重要方法是read()
  • public int read(); //返回:作为整数读取的字符(需要将int转char),如果已到达流的末尾,则返回 -1
  • public int read(char b[]);   //返回:读取的字符数
  • public int read(char[] b, int off, int len);
 
Writer类
与OutputStream类相似,都是输出流,但差别在于Writer类写入的是字符(char),而不是字节。
Writer的方法有:
  • public void write (int b);// 将参数b的低两字节写入到输出流
  • public void write (char b[]);// 将字符数组b[]中的全部字节顺序写入到输出流
  • public void write(char[] b, int off, int len);// 将字节数组b[]中从off开始的len个字节写入到流中
  • public void write( String s);// 将字符串写入流中
  • public void write( String s, int off, int len);// 将字符串写入流中, off为位置,len为长度
  • public void flush ();// 刷新流
  • public void close();// 关闭流
 
既然上面Reader、Writer、InputStream、OutputStream四类是根据每次操作的量以及输入输出划分出来的,那么就有其他的划分方式,划分为:节点流、处理流
节点流:可以向特定的地方(如文件)读写数据,如文件流FileInputStream、内存流ByteArrayInputStream.
处理流:可以对以及存在的流进行操作,也被称为过滤流(Filter),如缓冲处理流BufferedReader

上图是就是使用节点流和处理流的例子,先通过FileReader读入文件中的字符串,然后使用处理流对这个流进行处理,有了这个处理流后就不必通过节点流提供的read()一个一个进行读取,BufferedReader这个处理流提供了readLine()方法可以一次读出节点流中的一行。这样的两者结合起来的操作实现了对流的包装(链接)。

同时使用节点流和处理流的实际使用例子:
BufferedReader in =
                    new BufferedReader(new FileReader(file));
BufferedReader in2 =
            new BufferedReader(
                    new InputStreamReader(   //该处理流是字节流通向字符流的桥梁
                            new FileInputStream(file), “utf-8”));
s = in2.readLine();
从上图和例子看出,处理流构造时总是需要带一个其他流对象作为参数,一个流对象经过其他流的多次包装,称为流的链接。
通过节点流、处理流这样的划分方式,当我们进行I/O操作时,只需使用对应的数据类型对应的流,然后通过处理流进行链接,对流进行层层操作,便可以实现所需要的功能。
常用的节点流:
节点类型 字节流 字符流
File
文件
FileInputStream
FileOutputStream
FileReader
FileWriter
Memory Array
内存数组
ByteArrayInputStream
ByteArrayOutputStream
CharArrayReader
CharArrayWriter
Memory String
字符串
  StringReader
StringWriter
Pipe
管道
PipedInputStream
PipedOutputStream
PipedReader
PipedWriter
常用的处理流:
处理类型 字节流 字符流
Buffering
缓冲
BufferInputStream
BufferOutputStream
BufferedReader
BufferedWriter
Filtering
过滤
FilterInputStream
FilterOutputSteam
FilterReader
FilterWriter
Converting between bytes and character
字节流转换为字符流
  InputStreamReader
OutputStreamWriter
与字符编码有关
Object Serialization
对象序列化
ObjectInputStream
ObjectOutputStream
 
Data conversion
基本数据类型转化
DataInputStream
DataOutputStream
 
Counting
行号处理
LineNumberInputStream LineNumberReader
Peeking ahead 可回退流 PushbackInputStream PushbackReader
Pinting 可显示流 PrintStream PrintWriter
标准输入和输出
平时我们常用的System.in实际上是InputStream类型,而System.out、System.err为PrintStream类型,是一个字符输出流。平时用到的就是流,所以在使用的时候我们经常将System.in用各种处理流封装起来使用。如:
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
br.readLine();
在jdk1.5后增加了Scanner类,使用起来方便了些。
实例!常见内容(二进制、文本、对象)的读写:
二进制流的读写:
tip:IO中“二进制”指的是除了文本、对象之外的其他内容,在这里是一个比较笼统的概念

import java.io.*;

public class Dump {
public static void main(String[]args) {
try
{
dump( new FileInputStream("aaa.bmp"), //FileInputStream节点流
new FileOutputStream("bbb.bmp"));
}
catch(FileNotFoundException fex)
{
fex.printStackTrace();
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
} public static void dump(InputStream src, OutputStream dest) //这里使用InputStream、OutputStream类型作为参数
throws IOException
{
InputStream input = new BufferedInputStream(src); //使用处理流进行包装
OutputStream output = new BufferedOutputStream(dest); //向上转型
byte[] data = new byte[1024];
int length = -1;
while ((length = input.read(data)) != -1) { //read()将流中数据读取到data中
output.write(data, 0, length);
}
input.close();
output.close();
}
}
字符的读写:

import java.io.*;
public class CopyFileAddLineNumber {
public static void main (String[] args) {
//将文件的每一行注释去掉,然后加上行号
String infname = "CopyFileAddLineNumber.java";
String outfname = "CopyFileAddLineNumber.txt";
if( args.length >= 1 ) infname = args[0];
if( args.length >= 2 ) outfname = args[1]; try {
File fin = new File(infname);
File fout = new File(outfname); BufferedReader in = new BufferedReader(new FileReader(fin));
PrintWriter out = new PrintWriter(new FileWriter(fout)); int cnt = 0; // 行号
String s = in.readLine();
while ( s != null ) {
cnt ++;
s = deleteComments(s); //去掉以//开始的注释
out.println(cnt + ": \t" + s ); //写出
s = in.readLine(); //读入
}
in.close(); // 关闭缓冲读入流及文件读入流的连接.
out.close();
} catch (FileNotFoundException e1) {
System.err.println("File not found!" );
} catch (IOException e2) {
e2.printStackTrace();
}
} static String deleteComments( String s ) //去掉以//开始的注释
{
if( s==null ) return s;
int pos = s.indexOf( "//" );
if( pos<0 ) return s;
return s.substring( 0, pos );
}
}
序列化与反序列化(要求对象实现Serializable接口)
import java.io.*;
class Person implements Serializable
{
String name;
int age;
Person(String name, int age) {
this.name=name;
this.age=age;
}
public String toString() {
return name + "(" + age + ")";
}
}
public class SerializeDemo {
public static void main (String[] args)
throws IOException
{
Person [] ps = {
new Person("Li",18),
new Person("Wang",19)
};
String fileName = "s.temp";
//Serialize
ObjectOutputStream output = new ObjectOutputStream(
new FileOutputStream(fileName) );
for(Person p : ps) output.writeObject(p);
output.close();
//deserialize
ObjectInputStream input = new ObjectInputStream(
new FileInputStream(fileName) );
Person p = null;
try {
while( (p=(Person)input.readObject()) != null ) {
System.out.println(p);
}
} catch(ClassNotFoundException ex) {}
catch(EOFException eofex) {}
input.close();
}
}

浅入深出Java输入输出流主线知识梳理的更多相关文章

  1. 浅入深出之Java集合框架(中)

    Java中的集合框架(中) 由于Java中的集合框架的内容比较多,在这里分为三个部分介绍Java的集合框架,内容是从浅到深,如果已经有java基础的小伙伴可以直接跳到<浅入深出之Java集合框架 ...

  2. 浅入深出之Java集合框架(下)

    Java中的集合框架(下) 由于Java中的集合框架的内容比较多,在这里分为三个部分介绍Java的集合框架,内容是从浅到深,哈哈这篇其实也还是基础,惊不惊喜意不意外 ̄▽ ̄ 写文真的好累,懒得写了.. ...

  3. 浅入深出之Java集合框架(上)

    Java中的集合框架(上) 由于Java中的集合框架的内容比较多,在这里分为三个部分介绍Java的集合框架,内容是从浅到深,如果已经有java基础的小伙伴可以直接跳到<浅入深出之Java集合框架 ...

  4. 浅入深出Vue:环境搭建

    浅入深出Vue:环境搭建 工欲善其事必先利其器,该搭建我们的环境了. 安装NPM 所有工具的下载地址都可以在导航篇中找到,这里我们下载的是最新版本的NodeJS Windows安装程序 下载下来后,直 ...

  5. 浅入深出Vue:工具准备之PostMan安装配置及Mock服务配置

    浅入深出Vue之工具准备(二):PostMan安装配置 由于家中有事,文章没顾得上.在此说声抱歉,这是工具准备的最后一章. 接下来就是开始环境搭建了~尽情期待 工欲善其事必先利其器,让我们先做好准备工 ...

  6. 浅入深出Vue:工具准备之WebStorm安装配置

    浅入深出Vue之工具准备(一):WebStorm安装配置 工欲善其事必先利其器,让我们先做好准备工作吧 导航篇 WebStorm安装配置 所有工具的下载地址都可以在导航篇中找到,这里我们下载的是最新版 ...

  7. 『浅入深出』MySQL 中事务的实现

    在关系型数据库中,事务的重要性不言而喻,只要对数据库稍有了解的人都知道事务具有 ACID 四个基本属性,而我们不知道的可能就是数据库是如何实现这四个属性的:在这篇文章中,我们将对事务的实现进行分析,尝 ...

  8. 浅入深出Vue系列

    浅入深出Vue导航 导航帖,直接点击标题即可. 文中所有涉及到的资源链接均在最下方列举出来了. 前言 基础篇 浅入深出Vue:工具准备之WebStorm搭建及配置 浅入深出Vue之工具准备(二):Po ...

  9. 浅入深出Vue:前言

    浅入深出Vue系列文章 之前大部分是在做后端,后来出于某些原因开始接触Vue.深感前端变化之大,各种工具.框架令人眼花缭乱.不过正是这些变化,让前端开发更灵活. 博主在刚开始时,参考官网的各个步骤以及 ...

随机推荐

  1. 020、MySQL创建一个存储过程,显示存储过程,调用存储过程,删除存储过程

    一.我们创建一个MySQL储存过程,在SQL代码区写入以下内容,并执行就可以了 #编写一个存储过程 CREATE PROCEDURE ShowDate ( ) BEGIN #输出当前时间 SELECT ...

  2. IDE及PHP基础——注释、变量、数据、运算符、输出等

    IDE(Integrated Development Environment ),集成开发环境,是用于提供程序开发环境的应用程序,一般包括代码编辑器.编译器.调试器和图形用户界面等工具.集成了代码编写 ...

  3. HihoCoder第十一周:树中的最长路

    #1050 : 树中的最长路 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho得到了一棵二叉树玩具,这个玩具是由小球和木棍连接起来的,而在拆拼它的过程中, ...

  4. golang开启随机端口并获取端口

    listener, err := net.Listen("tcp", ":0") if err != nil { panic(err) } fmt.Printl ...

  5. python 鞍点

    # 鞍点: 所在行的最大值,所在列的最小值 import random A = [[random.randint(1,100) for j in range(5)]for i in range(5)] ...

  6. Docker Java 例子

    版权所有,未经许可,禁止转载 章节 Docker 介绍 Docker 和虚拟机的区别 Docker 安装 Docker Hub Docker 镜像(image) Docker 容器(container ...

  7. C#获取刚插入的数据的id

    在开发程序中我们经常会遇到两个表或多个表关联同时插入数据的需求. 那么我们刚给主表插入一条数据,接着给副表插入数据时其中一个字段要存储与主表关联的id,那么我们该怎么获取刚插入的那条数据的id呢?   ...

  8. 学习spring的第三天

    1.手动的依赖注入出了昨天所讲的利用<property>和<constructor-arg>标签设置注入外还可以通过属性值设置,这样就少些了一些代码... 1.1:直接在< ...

  9. caffe 官方demo python api

    Jupyter https://nbviewer.jupyter.org/github/BVLC/caffe/blob/master/examples/net_surgery.ipynb 涉及: - ...

  10. Junit学习使用

    InputStream in; SqlSessionFactory factory; SqlSession session; UserDao userDao; @BeforeEach public v ...