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. Day5 - F - 食物链 POJ - 1182

    动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A.现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种.有人用两种说法 ...

  2. maven加载ojdbc14报错

    问题复现步骤: 1.在pom.xml里面添加ojdbc14的依赖,代码如下: <dependency> <groupId>com.oracle</groupId> ...

  3. flower——知识总结

    创建主外键关联的话,外键表的外键字段一定要与主键表的主键字段相一致,包括字段类型,字段长度,字段符号等等 inverse="true" 将控制权交给对方,在一对多的关系中,一端控制 ...

  4. 记号一下用iptables做的端口转发

    iptables -t nat -I PREROUTING -p tcp -m tcp --dport 83 -j DNAT --to-destination 192.168.1.55:443ipta ...

  5. Windows安装tensorflow,配置vs2013,anaconda3.4,cudn9.0,cudnn7.0和pycharm

    前言 最近要开始学习深度,那么首先在电脑上安装tensorflow.但是我不知道是配置版本的问题,还是安装失误的问题,我安装了很久没有安装成功,最后重装了电脑,并且融合了所有的网上可以查到的方案才安装 ...

  6. 【剑指Offer】面试题32 - II. 从上到下打印二叉树 II

    题目 从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行. 例如: 给定二叉树: [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回 ...

  7. msf自动连接postgresql配置

    今天做了一下msf连接数据库的配置,中间碰到了一些坑点这里就不详细叙述了,开始正确的操作方式. 首先对postgresql进行配置以方便连接. root@kali:~# service postgre ...

  8. Percona-Toolkit 之 pt-kill 低效SQL

    [root@ tools]#vi ptkill_master.confuser=rootpassword=asd.123port=3306busy-time=5printkill /u01/soft/ ...

  9. python接口自动化26-发xml格式post请求《转载》

    python接口自动化26-发xml格式post请求 https://cloud.tencent.com/developer/article/1164987

  10. 福州大学2020年春软工实践W班第二次作业

    作业描述 这个作业属于哪个课程 福州大学2020年春软工实践W班 这个作业要求在哪里 寒假作业(2/2) 这个作业的目标 开发一个疫情统计程序 作业正文 福州大学2020年春软工实践W班第二次作业 其 ...