Java IO (二),常见的输入/输出流
字节流和字符流
InputStream和Reader
InputStream和Reader两个抽象类是所有输入流的基类,本身并不能创建实例来执行输入,但它们将成为所有输入流的模板.他们的方法是所有输入流都可用的方法.
InputStream中包含如下三个方法
int read()
从输入流中读取单个字节,返回所读取的字节数据(字节数据可直接转 换为int类型).int read(byte[] b)
从输入流中读取最多b.lenght
个字节数据,并将其存贮在数组b中,返回实际读取的字节数.int read(byte[] b,int off,int len)
从输入流中读取最多的len个字符的数据,并存在数组b中,放入数组b中时,从off的位置开始,返回实际读取的字节数.
Reader中包含如下三个方法
int read()
从输入流中读取单个字符,返回所读取的字符数据(字符数可以直接转换为int类型)int read(char[] cbuf)
从输入流中读取最多的cbuf.length个字符数据,并将其存储在字符数组cbuf中,返回实际读取的字符数.int read(char cbuf,int off,int len)
从输入流中读取最多len个字符的数据,并将其存在cbuf中,从off位置开始,返回实际的读取的字符数.使用FileInputStream读取自身
java
public void readFile() throws IOException {//创建字节输入流FileInputStream fis = new FileInputStram("FileInputTest.java");//创建一个长度为1024的缓冲数组byte[] bbuf = new byte[1024];//保存实际读取的字节数int hasRead = 0;//循环读取文件内容while ((hasRead = fis.read(bbuf)) > 0) {System.out.println(new String(bbuf,0,hasRead));}//文件IO资源不属于内存资源//垃圾回收无法回收该资源//必须显式关闭fis.close(); }
- 使用FileReader读取文件自身
public void readFile() throws IOException {FileReader fr = new FileReader("FileReaderTest.java");char[] cbuf = new char[32];int hasRead = 0;while ((hasRead = fr.read(cbuf)) > 0) {System.out.println(new String(cbuf,0,hasRead));}fr.clse();
}
此外,InputStream和Reader还支持如下几个方法来支持指针的移动
void mark(int readAheadLimit)
在记录指针当前位置记录一个标记(mark).
boolean markSupported()
判断此输入流是否支持mark()
操作
void reset()
将此流的记录指针重新定位到上一次记录标记的位置(mark).
long skip(long n)
记录指针向前移动n个字节/字符.
OutputStream和Writer
OutputStream和Writer也非常相似,两个流都提供了如下三个方法:
void write(int c)
将指定的字节/字符输出到输出流中,其中c既可以代表字节,也可以代表字符.void write(byte[]/char[] buf)
将字节数组/字符数组中的数据输出到指定输出流中.void write(byte[]/char[] buf,int off,int len)
将字节数组/字符数组从off位置开始,长度为len的字节/字符输出到输出流中.
Writer里还包含如下两个方法:
* void write(String str)
将str字符串输出到指定输出流中
* void write(String str,int off,int len)
将str字符串里从off位置开始,长度为len输出到指定输出流中.
下面的程序使用FileInputStream
来执行输入,通过FileOutputStream
执行输出,实现复制文件的功能
java
public void copyFile() throws IOException {FileInputStream fis = null;FileOutputStream fos = null;try {fis = new FileInputStream("outfile.txt");fos = new FileOutputStream("newfile.txt");byte[] bbuf = new byte[32];int hasRead = 0;while ((hasRead =fis.read(bbuf)) > 0) {fos.write(bbuf,0,hasRead);}} catch(IOException ioe) {ioe.printStatckTrance();} finally {if (fis != null) {fis.close();}if(fos != null) {fos.close();}} }
如果希望直接输出字符串内容,使用Writer更为方便.
java
public void out() {FileWriter fw = null;try {fw = new FileWrite("file.txt");fw.write("但我不能放歌,\n");fw.write("悄悄是别离的笙箫;\n");fw.write("夏虫也为我沉默,\n");fw.write("沉默是今晚的康桥!\n");} catch (IOException ioe) {} finally {if(null != fw) {fw.close();}} }
上面程序会在当前目录下输出file.txt,文件内容就是程序中输出内容.
输入/输出流体系
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
---|---|---|---|---|
抽象基类 | InputStream | OutputStream | Reader | Writer |
访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
访问数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
访问管道 | PipedInputStream | PipedOutputStream | PipedReader | PipedWriter |
访问字符串 | StringReader | StringWriter | ||
缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedRead | BufferedWriter |
转换流 | InputStreamReader | OutputStreamReader | ||
对象流 | ObjectInputStream | ObjectOutput | ||
抽象基类 | FilterInputStream | FilterOutPutStream | FilterReader | FilterWriter |
打印流 | PrintStream | PrintWriter | ||
推回输入流 | PushbackInputStream | PushbackReader | ||
特殊流 | DataInputStream | DataOutputStream |
上面表中粗体字标出类的代表节点流,必须直接与指定物理节点关联;斜体字标出的为抽象基类,无法创建实例.
字节流比字符流功能强大,因为计算机中所有数据都是二进制的.字节流可以处理所有的二进制文件.如果使用字节流来处理文本文件时,需要使用合适的方式把字节转换成字符,无形中增加了编程的复杂程度.所以通常有个规则,如果需要进行输入/输出的是文本内容,应考虑使用字符流,如果需要进行输入/输出的二进制内容,应考虑使用字节流.
使用字符串作为物理节点:
java
public void StringNodeTest() {String src = "软泥上的青荇,\n"+"油油的在水底招摇;\n"+"在康河的柔波里,\n"+"我甘心做一条水草。";StringReader sr = new StringReader(src);char[] cbuf = new char[32];int hasRead = 0;try {while((hasRead =sr.read(cbuf)) > 0) {System.out.println(new String(cbuf,0,hasRead));}} catch (IOException ioe) {ioe.} finally {if (null != sr){sr.close();}} }
转换流
IO体系中提供了2个转换流,用于实现将字节流转换成字符流.InputStreamReader
将字节输入流转换成字符输入流,OutputStreamWriter
将字节输出流转换成字符输出流.
Java并没有提供字符流转换成字节流接口,看似设计遗漏.考虑下字符流和字节流的差别,字节流比字符流使用范围更广,但字符流操作比字节流方便,如果已经有一个字符流,为什么还要换成字节流,既然知道字节流的内容是文本,那么转换成字符流更方便一些,所以Java没有提供字符流到字节流的转换.
下面的例子通过使用键盘输入(System.in
).这个标准的输入流是InputStream实例,使用起来不太方便,键盘输入的都是纯文本,使用InputStreamReader
将其转换为字符输入流,普通Reader
读起来依旧不方便,于是再转换成BufferedReader
,利用它的readLine()
方法可以一次读一行.
java
public void convInput() {BufferedReader br = null;try {//System.in转换成Reader对象InputStreamReader reader = new InputStreamReader(System.in);//将Reader包装成BufferedReaderbr = new BufferedReader(reader);String buffer = null;While((buffer = br.readLine()) != null) {if("exit".equals(buffer)) {System.exit(1);}System.out.println("输入内容为:" + buffer);}} catach (IOException ioe) {} finally {try {if (null != br) {br.close();}} catach (IOException ioe) {}} }
推回输入流
在IO体系中,有2个特殊的流.PushbackInputStream和PushbackReader.提供如下三个方法:
* void unread(byte[]/char[] buf)
将一个字节数组内容推回到推回缓冲区里,从而允许重复读取刚刚的内容.
* void unread(byte[]/char[] b,int off,int len)
将一个字节/字符数组从off开始,长度为len字节/ 字符的内容推回到推回缓冲区里,从而允许重复读取刚刚的内容.
* void unread(int b)
将一个字节/字符推回到推回缓冲区,从而允许重复读取刚刚读取的内容.
这三个方法和InputStream和Reader里三个read方法一一对应,这两个推回输入流都带有一个推回缓冲区,当程序调用这两个推回输入流的unread方法时,系统会把指定数组的内容推回到该缓冲区里,从而允许重复读取刚刚读取的内容.
java
/**省略无数代码**/PushbackReader pr = null;try {pr = new PushbackReader(new FileReader("E:\\workplace1\\review\\src\\io\\PushbackReaderTest.java"), 64);char[] buf = new char[32];//保存上次读取的字符串内容String lastContent = "";int hasRead = 0;while ((hasRead = pr.read(buf)) > 0) {//读取到内容转换成字符串String content = new String(buf,0,hasRead);int targetIndex = 0;//将上一次内容和本次内容拼起来 检查是否包含目标字符串//如果包含目标字符串if ((targetIndex = (lastContent + content).indexOf("new PushbackReader")) > 0) {//将本次内容上次内容一起退回到推回缓冲区pr.unread((lastContent + content).toCharArray());//再次读取指定程度的内容(目标字符串之前的内容)pr.read(buf,0,targetIndex);//打印读取内容System.out.println(new String(buf,0,targetIndex));System.exit(0);} else {System.out.println(lastContent);lastContent = content;}}/**省略无数代码**/
重定向标准输入/输出
Java的标准输入输出分别通过System.in和System.out来代表,默认情况下他们分别代表键盘和显示器.
System类中提供三个重定向输入/输出标准的方法:
* static void setErr(PrintStream err)
重定向"标准"错误输出流
* static void setIn(InputStream in)
重定向"标准"输入流
* static void setOut(PrintStream out)
重定向"标准"输出流
下面的程序通过重定向标准输出流,将System.out的输出重定向到到文件输出:
java
/**省略无数代码**/PrintStream ps = null;try {//创建重定向需要的输出流ps = new PrintStream(new FileOutputStream("out.txt"));//将标准输出流重定向到ps输出流System.setOut(ps);//测试输出System.out.println("普通字符串");System.out.println(new RedirectOut());} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {if (null != ps) {ps.close();}} /**省略无数代码**/
下面的程序通过重定向标准输入流,将System.in重定向到指定文件而不是键盘:
java
/**省略无数代码**/FileInputStream fis = null;try {fis = new FileInputStream("E:\\workplace1\\review\\src\\io\\RedirectIn.java");//将标准输入重定向到fis输入流System.setIn(fis);//获取标准输入Scanner sc = new Scanner(System.in);//设置只把回车作为分隔符sc.useDelimiter("\n");while (sc.hasNext()) {System.out.println("键盘输入内容为:" + sc.next());} /**省略无数代码**/
Java IO (二),常见的输入/输出流相关推荐
- Java基础(二):集合、IO流(Zip压缩输入/输出流等)、File文件类、反射、枚举
Java基础(一):编译和解释.数据类型.变量作用域.String常用方法.数组.面向对象.异常 Java基础(二):集合.IO流(Zip压缩输入/输出流等).File文件类.反射.枚举 Java异常 ...
- java输出流输入流的使用_Java中的IO流之文件输入输出流
Java中的IO流之文件输入输出流 1.文件流介绍 文件流是以字节为单位进行读写文件的,所以属于字节流,并且是低级流.文件流位于java.io包下. 输入输出流分别是FileInputSteam和Fi ...
- 【Java学习笔记十】输入输出流
在Java.io包中提供了一系列用于处理输入/输出的流类.从功能上分为两类:输入流和输出流.从六结构上可分为:字节流(以字节为处理单位)和字符流(以字符为处理单位). 字符是由字节组成.在Java中所 ...
- java out.flush_java中基本输入输出流的解释(flush方法的使用)
网络程序的很大一部分是简单的输入输出,即从一个系统向另一个系统移动字节.字节就是字节,在很大程度上,读服务器发送的数据与读取文件没什么不同:向客户传送数据与写入一个文件也没有什么区别. Java中输入 ...
- java输入输出及文件_java输入输出流及文件操作
我只选择了一些代码 注意包声明和相关结构 许多类都继承了MyFile这个类 深入研究可以参考<java文件操作> 1.[代码]读取文件内容 /** *Author:Yuanhonglong ...
- 1.1 Java流是什么?输入/输出流又是什么?
在 Java 中所有数据都是使用流读写的.流是一组有序的数据序列,将数据从一个地方带到另一个地方.根据数据流向的不同,可以分为输入(Input)流和输出(Output)流两种. 在学习输入和输出流之前 ...
- java 对象读写_java 对象输入输出流读写文件的操作实例
java 对象输入输出流读写文件的操作实例 java 支持对对象的读写操作,所操作的对象必须实现Serializable接口. 实例代码: package vo; import java.io.Ser ...
- java inputstream read_Java学习之输入输出流
"持志如心痛,一心在痛上,岂有功夫说闲话,管闲事 --摘自阳明先生语录" Java中通过流来完成输入/输出,所有的输入/输出以流的形式处理,流可以理解为一个数据的序列.输入流表示从 ...
- Java IO(二)
字节流 字符流: FileReader FileWriter BufferedReader BufferedWriter 字节流: FileInputStream FileOutputStream B ...
最新文章
- 微软:外接 USB 设备或 SD 卡时将无法更新 Windows 1903
- ASP.NET防止按F5键造成表单重复提交
- 高手是如何定位内存问题的代码位置的
- 矩阵快速幂各类题型总结(一般,共轭,1 * n, 矩阵简化)
- 数据离散化 - 等宽等频聚类离散 - Python代码
- Qt学习笔记-Qt程序切换皮肤
- 浅谈Fluent Ribbon 中的SplitButton
- phpcmsV9中的CSS_PATH是如何定义的
- 突破技术管理,IT人中年危机变契机
- 高通:骁龙将成为独立的产品品牌
- mysql多线程复制binlog_MySQL并发复制系列一:binlog组提交 (转载)
- 二十年前的电脑配置单,大家见过吗?
- mysql增加列并增加comment_运城多条高铁线路调整动车列数增加到99列
- 电脑版微信发消息转圈圈
- 掌握QCC推行方法,为企业创造经济效益
- 购买成功订单详情html,订单成功页面功能实现
- 第三方百度地图----显示所在位置
- vue 运行项目浏览器页面显示“该网页无法正常运作”
- 计算机设置休眠密码,win10系统如何设置电脑待机密码?windows10设置待机密码图文教程...
- 全网最全软件测试面试题,拿不到offer算我输!
热门文章
- Linux环境变量设置中配置文件分析(/etc/profile,~/.bashrc等)(转)
- Deep Learning(深度学习)相关网站
- mac环境下的linux光标快捷键
- 一段经典的js命名空间创建和链式调用代码
- 创新创新再创新(4)
- 黄聪:ICTCLAS分词系统研究(一)(转)
- VI连接esx主机时报错“client.xml”错误
- python画图保存成html格式、用浏览器打开页面为空白_解决pyecharts运行后产生的html文件用浏览器打开空白...
- IPv6 — IPv4v6 综合组网技术
- Keil 函数内联 inline