目录:

一、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. 2017-2018-2 1723《程序设计与数据结构》第八周作业 & 实验二 & 第一周结对编程 总结

    作业地址 第八周作业:https://edu.cnblogs.com/campus/besti/CS-IMIS-1723/homework/1847 (作业界面已评分,可随时查看,如果对自己的评分有意 ...

  2. 初学Java必写的小程序。

    1.矩形面积,周长封装测试. /** * @author Administrator *封装好的矩形类 *自己私有的长宽属性 *开放 求面积求周长的方法 和设置长宽的方法 */ public clas ...

  3. HP 4411s Install Red Hat Enterprise Linux 5.8) Wireless Driver

    pick up from http://blog.163.com/wangkangming2008%40126/blog/static/78277928201131994053617/ # cp iw ...

  4. Vue的filter属性

    Vue.filter('sss',function(data){ //可以使用逻辑处理数据 data += '123'; return data*10; }) new Vue({ el:'#app', ...

  5. [转帖]Linux的进程线程及调度

    Linux的进程线程及调度 本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10393707.html 本文为宋宝华<Linux的进程 ...

  6. 3.27PSP及体会

    首先,我还是第一次了解老师这种先喂鸡汤,再打鸡血的行为,大老板的出现让我有些措手不及,我 的 天 啊! 话说这周alpha版本实现,真的是好费脑筋,因为预定是4~6周的项目一周弄完,而且还是在拥有几个 ...

  7. 关于mybatis的@Param注解和参数

    1,使用@Param注解 当以下面的方式进行写SQL语句时: @Select("select column from table where userid = #{userid} " ...

  8. hive数据查询

    Fetch task 丢弃了mapreduce的作业的繁重任务,查询方便简单 1.第一种方式 2.linux命令行 3.地3中

  9. 下载 Internet Explorer 11(脱机安装程序)

    https://support.microsoft.com/zh-cn/help/18520/download-internet-explorer-11-offline-installer 语言  本 ...

  10. 【gridview增删改查】数据库查询后lodop打印

    ASP.NET中使用gridview可以很容易的把需要的数据动态显示在前台,还可以在表格里加入列进行增删改查,每次点击的时候重新加载数据,gridview也提供了分页等功能,还有一些模版让显示在前台的 ...