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. Tasks、 activity 及 activity stack - 人间奇迹(转)

      http://www.cnblogs.com/yaozhongxiao/p/3365345.html Activity之间的跳转,或者说加载一个新的Activity,一般对于开发者来说,都不是一个 ...

  2. Spark Scheduler 模块(上)

    在阅读 Spark 源代码的过程中,发现单步调试并不能很好的帮助理解程序.这样的多线程的分布式系统,更好的阅读源代码的方式是依据模块,分别理解.   在包 org.apache.spark 下面有很多 ...

  3. 7.6 CLI 管理Varnish

    ./varnishd -f /usr/common/varnish/etc/varnish/ -a 测试: 代理tomcat服务器地址:http://172.20.10.5:1111/ telnet ...

  4. SQL注入汇总(手注,盲注,报错注入,宽字节,二次编码,http头部){10.22、23 第二十四 二十五天}

    首先什么是SQL注入: 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令. SQL注入有什么危害? 危害:数据泄露.脱库 ...

  5. Web系统测试的常用方法总结-18《转载》

    Web系统测试的常用方法归纳 --- 知识记录 1.页面链接检查 每一个链接是否都有对应的页面,并且页面之间切换正确.可以依靠一些工具,如:LinkBotPro.File-AIDCS.HTML Lin ...

  6. 如何创建一个Asp .Net Web Api项目

    1.点击文件=>新建=>项目 2.创建一个Asp .NET Web项目 3.选择Empty,然后选中下面的MVC和Web Api,也可以直接选择Web Api选项,注意将身份验证设置为无身 ...

  7. SQL语句对MySQL数据库的操作之对数据库层面的操作

    一.数据库内部存储结构 字段->数据表->数据库->MySQL服务器 二.登录及退出数据库 mysql -h服务器地址 -u用户名 -p密码(这样的登录形式并不安全) mysql - ...

  8. POJ 1177/HDU 1828 picture 线段树+离散化+扫描线 轮廓周长计算

    求n个图矩形放下来,有的重合有些重合一部分有些没重合,求最后总的不规则图型的轮廓长度. 我的做法是对x进行一遍扫描线,再对y做一遍同样的扫描线,相加即可.因为最后的轮廓必定是由不重合的线段长度组成的, ...

  9. Docker 容器(container)

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

  10. sed -i添加到第一行

    用sed的i\命令在第一行前面插入即可,加上 -i 选项直接操作文件. sed -i '1i\要添加的内容' yourfile 查看插入第一行是否成功 sed -n '1,1p' yourfile