十、java_IO
目录:
一、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的更多相关文章
- Java_io体系之BufferedWriter、BufferedReader简介、走进源码及示例——16
Java_io体系之BufferedWriter.BufferedReader简介.走进源码及示例——16 一:BufferedWriter 1.类功能简介: BufferedWriter.缓存字符输 ...
- 前端开发中SEO的十二条总结
一. 合理使用title, description, keywords二. 合理使用h1 - h6, h1标签的权重很高, 注意使用频率三. 列表代码使用ul, 重要文字使用strong标签四. 图片 ...
- 谈谈一些有趣的CSS题目(十二)-- 你该知道的字体 font-family
开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...
- 如何一步一步用DDD设计一个电商网站(十)—— 一个完整的购物车
阅读目录 前言 回顾 梳理 实现 结语 一.前言 之前的文章中已经涉及到了购买商品加入购物车,购物车内购物项的金额计算等功能.本篇准备把剩下的购物车的基本概念一次处理完. 二.回顾 在动手之前我对之 ...
- CSS十问——好奇心+刨根问底=CSSer
最近有时间,想把酝酿的几篇博客都写出来,今天前端小学生带着10个问题,跟大家分享一下学习CSS的一些体会,我觉得想学好CSS,必须保持一颗好奇心和刨根问底的劲头,而不是复制粘贴,得过且过.本人能力有限 ...
- WCF学习之旅—第三个示例之四(三十)
上接WCF学习之旅—第三个示例之一(二十七) WCF学习之旅—第三个示例之二(二十八) WCF学习之旅—第三个示例之三(二十九) ...
- 谈谈一些有趣的CSS题目(十)-- 结构性伪类选择器
开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...
- CRL快速开发框架系列教程十二(MongoDB支持)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- CRL快速开发框架系列教程十(导出对象结构)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
随机推荐
- linux-shell-引用-命令替换-命令退出状态-逻辑操作符
命令替换:bash7步扩展的之一 嵌套 这里没什么意义 退出状态可以参与逻辑判断 表达式 算数表达式和条件表达式,逻辑表达式 查看passwd命令比,避免用户捕获输入密码的接口 这种方式就可以直接输 ...
- 个人博客作业-Week2 (代码规范, 代码复审)
代码规范: 1.这些规范都是官僚制度下产生的浪费大家的编程时间.影响人们开发效率, 浪费时间的东西. 编码规范它包含了代码格式,还包括了编码风格和其他规范,通常涉及:缩进.空格使用.Tab使用 注释. ...
- M2事后总结
照片 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? "北航"Clubs旨在于解决北航校内社团管理与学生参与社团活动的困难的 ...
- Java提高篇(1)封装
三大特性之---封装 封装从字面上来理解就是包装的意思,专业点就是信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能 ...
- 关于EA和ED的区别
在申请美国大学本科的过程中,申请的截止时间往往分为两轮:提前申请(Early Decision/Action) 和常规申请 (Regular Decision).提前申请,顾名思义,截止时间会相对早一 ...
- jstack 使用一例
31jstack -m -F 2340 >libra.log 2>&1 jstack -m -F 2340 >libra2.log 2&>1 jstack -m ...
- HTML 5 placeHolder
<html> <body> <input type="text" id="idNum" placeholder="pla ...
- jquery的extend方法(源码解析)
1.前段时间一直忙于研究数据可视化(d3.js,three.js) 以及 php的 laravel框架,生活上也遇到很多事情,这大概就是人生中的迷茫期吧. 回想起,刚出来工作的时候,目标很明确,要学习 ...
- 项目引入android-support-v7-appcompat遇到的问题,no resource found that matches the given name 'android:Theme.AppCompat.Light'
一.问题 今天准备使用v7包中的ToolBar来用,但是在styles.xml中引入Theme.AppCompat.Light的时候,报错“no resource found that matches ...
- centos 7 修改系统屏幕分辨率
centos 7 修改系统屏幕分辨率,命令方式和图形方式的修改方法. 命令:xrandr 通过命令 xrandr 修改系统的分辨率,输入xrandr: bash [admin@localhost ~] ...