目录:

一、java流式输入/输出原理

二、java流类的分类

三、输入/输出流类

四、常见的节点流和处理流

五、文件流

六、缓冲流

七、数据流

八、转换流

九、Print流

十、Ubject流

一、java流式输入/输出原理

java中,对于数据的输入/输出操作以”流”(Stream)方式进行;JDK提供了各种各样的”流”类,用以获取不同类型的数据;程序中通过标准的方法输入或输出数据

二、java流类的分类

  • 按数据流的方向不同可以分为输入流和输出流
  • 按处理数据单位不同可以分为字节流和字符流
  • 按照功能不同可以分为节点流和处理流

jdk所提供的所有流类型位于包java.io内,分别继承自以下四种抽象流类型

  字节流 字符流
输入流 InputStream Reader
输出流 OutputStrean Writer

节点流:可以从一个特定的数据源(节点)读写数据(如:文件、内存)

处理流:是链接已存在的流(节点流或处理流)纸上,通过对数据的处理为程序提供更为强大的读写功能

三、输入/输出流类

1.InputStream

继承自InputStream的流都是用于向程序中输入数据,且数据的单位为字节(8bit);下图中神色为节点流,浅色为处理流

InputSream的基本方法:

//读取一个字节并以整数的形式返回(0-255),如果返回-1则已经到输入流的末尾
int read() throws IOException
//读取一系列字节并存储到一个数组buffer,返回实际读取的字节数。如果读取前已经到输入流的末尾返回-1
int read(byte[] buffer) throws IOException
//读取length个字节,并存储到一个字节数组buffer,从length位置开始,返回实际读取的字节数,如果读取前已经到输入流的末尾返回-1
int read(byte[] buffer, int offset, int length) throws IOException
//关闭流释放内存资源
void close() throws IOException
//跳过n个字节不读,返回实际跳过的字节数
long skip(long n) throws IOException

2.OutputStream

继承自OutPutStream的流是用于程序输出数据,且数据的单位为字节(8bit);下图中神色为节点流,浅色为处理流

OutputStream的基本方法:

//向输出流中写入一个字节数据,该字节数据为参数b的低8位
void write(int b) throws IOException
//将一个字节类型的数组中的数据写入输出流
void write(byte[] b) throws IOException
//将一个字节类型的数组中的从指定位置(off)开始的len个字节写入到输出流
void write(byte[] b, int off, int len) throws IOException
//关闭流释放内存资源
void close() throws IOException
//将输出流中还从的数据全部写入到目的地
void flush() throws IOException

3.Reader

继承自Reader的流都是用于向程序中输入数据,且数据的单位为字符(16bit);下图中神色为节点流,浅色为处理流

Reader的基本方法:

//读取一个字符并以整数的形式返回(0-255),如果返回-1则已经到输入流的末尾
int read() throws IOException //读取一系列字符并存储到一个数组buffer,返回实际读取的字符数。如果读取前已经到输入流的末尾返回-1
int read(char[] buffer) throws IOException //读取length个字符,并存储到一个字符数组buffer,从length位置开始,返回实际读取的字符数,如果读取前已经到输入流的末尾返回-1
int read(char[] buffer, int offset, int length) throws IOException //关闭流释放内存资源
void close() throws IOException //跳过n个字符不读,返回实际跳过的字符数
long skip(long n) throws IOException

4.Writer

继承自writer的流都是用于程序中输出数据,且数据的单位为字符(16bit);下图中神色为节点流,浅色为处理流

Writer常用方法

//向输出流中写入一个字符数据,该字符数据为参数b的低16位
void write(int b) throws IOException //将一个字符类型的数组中的数据写入输出流
void write(char[] b) throws IOException //将一个字符型的数组中的从指定位置(off)开始的len个字符写入到输出流
void write(char[] b, int off, int len) throws IOException //将一个字符串中的字符写入到输出流
void wrete(String string) throws IOException //将一个字符串从offset开始的length个字符写入到输出流
void write(String string, int offset, int length) throws IOException //关闭流释放内存资源
void close() throws IOException //将输出流中还从的数据全部写入到目的地
void flush() throws IOException

四、常见的节点流和处理流

1.节点流类型:

2.处理流类型:

五、文件流

FileInputStream和FileOutputStream分别继承自InputStream和OutputStream用于向文件中输入和输出字节

FileInputStream和FileOutputStream常用构造方法:

FileInputStream(String name) throws FileNotFoundException
FileInputStream(File file) throws FileNotFoundException
FileOutputStream(String name) throws FileNotFoundException
FileOutputStream(File file) throws FileNotFoundException
FileOutputStream(File file,boolean append) throws FileNotFoundException

FileInputStream和FileOutputStream类支持其父类InputStream和OutputStream所提供的数据读写方法。

注意:

  • 在实例化FileInputStream和FileOutputStraeam流时要用try-catch语句来处理其可能抛出的FileNotFoundException
  • 在读写数据时也要用try-catch语句来处理可能抛出IOException
  • FileNotFoundException是IOException的子类

FileInputStream:

public class Test{
public static void main(String[] args) { int b = 0 ;
FileInputStream in = null;
//打开文件
try {
in = new FileInputStream("F:\\test.txt");//windows下路径分隔符是两个反斜杠,也可以直接使用正斜杠
} catch (FileNotFoundException e) {
System.out.println("找不到指定文件");
System.exit(-1);
}
//读取文件
try {
long num = 0;
while((b = in.read()) != -1) {
System.out.print((char)b);
num++;
}
in.close();
System.out.println();
System.out.print("共读取了 "+ num +" 个字节");
} catch (IOException e1) {
System.out.println("文件读取错误");
System.exit(-1);
} }
}

FileOutputStream:

public class Test{
public static void main(String[] args) { int b = 0 ;
FileInputStream in = null;
FileOutputStream out = null;
//打开文件
try {
in = new FileInputStream("F:\\test.txt");//windows下路径分隔符是两个反斜杠,也可以直接使用正斜杠
out = new FileOutputStream("F:/test1.txt");//如果目录下没有这个文件FileOutputStream会自动生成一个
while((b = in.read()) != -1) {
out.write(b);//一个个字节写进去
}
in.close();//管道用完记得关闭
out.close();
} catch (FileNotFoundException e) {
System.out.println("找不到指定文件");
System.exit(-1);
} catch (IOException e1) {
System.out.println("文件复制错误");
System.exit(-1);
}
System.out.print("复制成功");
}
}

FileReader:

public class Test{
public static void main(String[] args) { FileReader fr = null;
int c = 0;
try {
fr = new FileReader("f:/test.txt");
int in = 0;
while ((c = fr.read()) != -1) {
System.out.print((char)c);
}
} catch (FileNotFoundException e) {
System.out.print("找不到指定文件");
} catch (IOException e1) {
System.out.print("文件读取错误");
} }
}

FileWriter:

public class Test{
public static void main(String[] args) { FileReader fr = null;
FileWriter wr = null;
int c = 0;
try {
fr = new FileReader("f:/test.txt");
wr = new FileWriter("f:/test1.txt");
int in = 0;
while ((c = fr.read()) != -1) {
wr.write(c);
}
wr.close();
fr.close();
} catch (FileNotFoundException e) {
System.out.print("找不到指定文件");
} catch (IOException e1) {
System.out.print("文件写入错误");
}
}
}

六、缓冲流

缓冲流要”套接”在相应的节点流纸上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法

JDK提供了四种缓冲流,其常用的构造方法为:

BufferedReader(Reader in)
BufferedReader(Reader in,int sz)//sz为自定义缓冲区的大小
BufferedWriter(Writer out)
BufferedWriter(Writer out,int sz)
BufferedInputStream(InputStream in)
BufferedInputStream(InputStream in, int sz)
BufferedOutputStream(OutputStream out)
BufferedOutputStream(OutputStream out, int sz)
  • 缓冲流输入支持其父类的mark和reset方法
  • BufferedReader提供了readLine方法用于读取一行字符串(以\r 或\n分割)
  • BufferedWriter提供了newLine用于写入一个行分隔符
  • 对于输出的缓冲流,写出的数据会现在内存中缓存,使用flush方法将会使内存中的数据立刻写出

BufferStream1:

public class Test{
public static void main(String[] args) { try {
FileInputStream fis = new FileInputStream("f:/test.txt");
BufferedInputStream bis = new BufferedInputStream(fis);//相当于管道套管道,为了使用缓冲区的功能
int c = 0;
System.out.println((char)bis.read());
System.out.println((char)bis.read()); bis.mark(100);//从100个开始往外读
for(int i=0; i<10 && (c=bis.read()) != -1; i++) {
System.out.print((char)c + " ");
}
System.out.println();
bis.reset();//回到100的那个点上
for(int i=0; i<=10 && (c=bis.read()) != -1; i++) {
System.out.print((char)c + " ");
}
bis.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}

BufferStream2:

public class Test{
public static void main(String[] args) { try {
BufferedWriter bw = new BufferedWriter(new FileWriter("f:/test.txt"));//管道套接
BufferedReader br = new BufferedReader(new FileReader("f:/test.txt"));
//写入
String s = null;
for(int i=1; i<100; i++) {
s = String.valueOf(Math.random());//产生一个字符串的随机数
bw.write(s);//写一个字符串到缓冲区
bw.newLine();//写一个换行到缓冲区
}
bw.flush();//将缓存内存中的数据写出
//逐行读取
while((s=br.readLine()) != null) {
System.out.println(s);
} bw.close();
br.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}

七、数据流

  • DataInputStream和DataOutPutStream分别继承自InputStream和OutPutStream,它属于处理流,需要分别”套接”在InputStream和OutputStream类型的节点流上
  • DataInputStream和DataOutputStream提供了可以存取与机器无关的java原始类型数据(如:int,double等)的方法
  • DataInputStream和DataOutputStream的构造方法为:
DataInputStream(InputStream in)
DataOutputStream(OutputStream out)

看一个例子:

public class Test{
public static void main(String[] args) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();//在内存中分配字节数组
DataOutputStream dos = new DataOutputStream(baos);//套接 try {
dos.writeDouble(Math.random());//写一个double类型的随机数,double是8个字节
dos.writeBoolean(true);//写一个布尔值进去,布尔值在内存中只占一个字节
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());//读数据,只能一个字节一个字节读
System.out.println(bais.available());//输出字节数 DataInputStream dis = new DataInputStream(bais);//套接
System.out.println(dis.readDouble());//输出数据1,注意,先写的先读
System.out.println(dis.readBoolean());//输出数据2
dos.close();
dis.close(); } catch(IOException e) {
e.printStackTrace();
}
}
}

八、转换流

  • InputStreamReader和OutputStreamWriter用于字节数据到字符数据之间的转换
  • InputStreamReader需要和InputStream”套接”
  • OutputStreamWriter需要和OutputStream”套接”
  • 转换流在构造时可以指定其编码集合,例如:InputStream isr = new InputStreamReader(System.in, “ISO8859_1”)

OutputStreamWriter:

public class Test{
public static void main(String[] args) { try {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("f:/test.txt"));
osw.write("aaa");
System.out.println(osw.getEncoding()); //获取osw的字符编码
osw.close();
//true表示在原文件的基础上追加,如果不加true,则会删除原文件的内容后再写入新的内容,ISO8859_1是一种字符编码,指定了要写入内容的编码格式
osw = new OutputStreamWriter(new FileOutputStream("f:/test.txt", true), "ISO8859_1");
osw.write("bbb");
System.out.println(osw.getEncoding());
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

InputStreamReader:

/*
* 这个程序相当于一直逐行读取键盘输入,直到输入exit为止,这是一种阻塞式的方法,程序运行起来后不输入exit程序就一直停在那,也可以理解为是同步式的
*/ public class Test{
public static void main(String[] args) {
InputStreamReader isr = new InputStreamReader(System.in);//System.in是接收的键盘输入
BufferedReader br = new BufferedReader(isr);
String s = null; try {
s = br.readLine();
//除非s="exit"否则就不停的读
while(s != null) {
if(s.equalsIgnoreCase("exit")) {
break;
} else {
System.out.println(s.toUpperCase());
s = br.readLine();
}
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

九、Print流

  • PrintWriter和PrintStream都属于输出流,分别针对与字符和字节
  • PrintWriter和PrintStream提供了重载的print
  • Println方法用于多种数据类型的输出
  • PrintWriter和PrintStream的输出操作不会抛出异常,用户通过检测错误状态获取错误信息
  • PrintWriter和PrintStream有子的佛那个flush功能
PrintWriter(Writer out)
PrinWriter(Writer out,boolean autoFlush)
PrintWriter(OutputStream out)
PrintWriter(PutputStream out, boolean autoFlush)
PrintStream(OutputStream out)
PrintStream(OutputStream out, boolean autoFlush)

例子1:

public class Test{
public static void main(String[] args) {
PrintStream ps = null; try {
FileOutputStream fos = new FileOutputStream("f:/test.txt");
ps = new PrintStream(fos);//套接
} catch(IOException e) {
e.printStackTrace();
} if(ps != null) {
System.setOut(ps);//更改默认输出位置为ps,System.out默认指向的是控制台
} int ln = 0;
for(char c=0; c<=60000; c++) {
System.out.print(c+" ");
if(ln++ >= 100) {
System.out.println();
ln = 0;
}
}
}
}

例子2:

public class Test{
public static void main(String[] args) {
String filename = args[0];//外部传参
if(filename != null) {
list(filename,System.out);
}
}
public static void list(String f,PrintStream fs){
try {
BufferedReader br = new BufferedReader(new FileReader(f));
String s = null;
//按行读取
while((s=br.readLine()) != null) {
fs.println(s);
}
br.close();
} catch(IOException e) {
fs.println("无法读取文件");
}
}
}

例子3:

public class Test{
public static void main(String[] args) {
String s = null;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//System.in是键盘输入 try {
FileWriter fw = new FileWriter("f:/test.txt",true);//true追加在原文件后面
PrintWriter log = new PrintWriter(fw); while((s=br.readLine()) != null){
if(s.equalsIgnoreCase("exit")){
break;//如果键盘输入exit则停止运行
} System.out.println(s.toUpperCase());//控制台输出
log.println("----");
log.println(s.toUpperCase());//写入
log.flush();
}
log.println("==="+new Date()+"===");//new Date()指的是util里的date,也就是当前时间
log.flush();
log.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}

十、Ubject流

作用:直接将Object写入或读出

  • transient关键字
  • serializable接口      标记类里的对象可以序列化
  • externalizable接口    控制类的对象是怎么写出去的,也就是说可以自己控制序列化过程

看一个例子:

class T implements Serializable{//如果要写入或者读对象必须要实现Serializable接口,这是一个标记接口,所以不需要重写方法
int i = 0;
int j = 9;
double d = 2.3;
int k = 0;
}
public class Test{
public static void main(String[] args) throws Exception{
T t = new T();
t.k = 8;
FileOutputStream fos = new FileOutputStream("f:/test.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(t);//把t对象写入f:/test.txt
oos.flush();
oos.close(); FileInputStream fis = new FileInputStream("f:/test.txt");
ObjectInputStream ois = new ObjectInputStream(fis); T tReaded = (T)ois.readObject();//读对象
System.out.println(tReaded.i+" "+tReaded.j+" "+tReaded.d+" "+tReaded.k);
}
}

上面例子中的输出结果为:0    9    2.3    8

如果将T里的 int k = 0; 改为 transient int k = 0;

则输出结果应该是0    9    2.3    0

因为transient相当于把k变成了透明的,使用transient修饰的成员变量在序列化(操作对象)的时候不予考虑

十、java_IO的更多相关文章

  1. Java_io体系之BufferedWriter、BufferedReader简介、走进源码及示例——16

    Java_io体系之BufferedWriter.BufferedReader简介.走进源码及示例——16 一:BufferedWriter 1.类功能简介: BufferedWriter.缓存字符输 ...

  2. 前端开发中SEO的十二条总结

    一. 合理使用title, description, keywords二. 合理使用h1 - h6, h1标签的权重很高, 注意使用频率三. 列表代码使用ul, 重要文字使用strong标签四. 图片 ...

  3. 谈谈一些有趣的CSS题目(十二)-- 你该知道的字体 font-family

    开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

  4. 如何一步一步用DDD设计一个电商网站(十)—— 一个完整的购物车

     阅读目录 前言 回顾 梳理 实现 结语 一.前言 之前的文章中已经涉及到了购买商品加入购物车,购物车内购物项的金额计算等功能.本篇准备把剩下的购物车的基本概念一次处理完. 二.回顾 在动手之前我对之 ...

  5. CSS十问——好奇心+刨根问底=CSSer

    最近有时间,想把酝酿的几篇博客都写出来,今天前端小学生带着10个问题,跟大家分享一下学习CSS的一些体会,我觉得想学好CSS,必须保持一颗好奇心和刨根问底的劲头,而不是复制粘贴,得过且过.本人能力有限 ...

  6. WCF学习之旅—第三个示例之四(三十)

           上接WCF学习之旅—第三个示例之一(二十七)               WCF学习之旅—第三个示例之二(二十八)              WCF学习之旅—第三个示例之三(二十九)   ...

  7. 谈谈一些有趣的CSS题目(十)-- 结构性伪类选择器

    开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

  8. CRL快速开发框架系列教程十二(MongoDB支持)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  9. CRL快速开发框架系列教程十(导出对象结构)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

随机推荐

  1. 代码规范与复审2——个人博客作业week

    一.关于编程规范的重要性论证 1.不支持. 1)编程规范有利于自己提高编程效率和编程质量.编码是程序员的职责,一个好的信息技术产品必然有高质量的代码,高质量的代码首先 一点它必须遵守某种编程规范.如果 ...

  2. BugPhobia开发篇章:Beta阶段第VIII次Scrum Meeting

    0x01 :Scrum Meeting基本摘要 Beta阶段第八次Scrum Meeting 敏捷开发起始时间 2015/12/22 00:00 A.M. 敏捷开发终止时间 2015/12/22 23 ...

  3. StringBuffer的append方法比“+”高效

    在字符串的连接过程中StringBuffer的效率要比String高: string操作代码: String str = new String("welcome to "); st ...

  4. Practice5.1 测试与封装5.1

    结对同伴: 姓名 学号 博客地址 叶子鹏 201306114420 http://www.cnblogs.com/kazehanaai/ 王佳宁 201306114434 http://www.cnb ...

  5. ios开发之--CAKeyframeAnimation的详细用法

    简单的创建一个带路径的动画效果,比较粗糙,不过事先原理都是一样的, 代码如下: 1,创建动画所需的view -(void)creatView { moveView = [UIView new]; mo ...

  6. 【转】GPS定位准确度CEP、RMS

    转自:http://blog.sina.com.cn/s/blog_70f96fda0101lcb9.html CEP和RMS是GPS的定位准确度(俗称精度)单位,是误差概率单位.就拿2.5M CEP ...

  7. Ajax cross domain

    xhrFields:{ withCredentials:true}, https://stackoverflow.com/questions/2054316/sending-credentials-w ...

  8. Max length of title attribute in html

    测了一下chrome是1024个utf-8字符. 具体可见: http://stackoverflow.com/questions/8516235/max-length-of-title-attrib ...

  9. Cmder 常用配置

    windows 系统的 cmd 命令窗口不是很好用,可以试试 Cmder 工具包. 1.在运行框中快速启动 Cmder 将 cmder.exe 文件所在目录加载环境变量 PATH 中. 2.把 cms ...

  10. React 模板

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...