彻底明白Java语言中的IO系统

ava的核心库java.io提供了全面的IO接口,包括:文件读写,标准设备输出等等。Java中IO是以流为基础进行输入输出的,所有数据被串行化写入输出流,或者从输入流读入。在具体使用中很多初学者对Java.io包的使用非常含糊,本文将详细解说关于Java.io的使用。

一. Input和Output 

1. stream代表的是任何有能力产出数据的数据源,或是任何有能力接收数据的接收源。在Java的IO系统中,所有的stream(包括Input和Out stream)都包括两种类型:

1.1 以字节为导向的stream

以字节为导向的stream,表示以字节为单位从stream中读取或往stream中写入信息。以字节为导向的stream包括下面几种类型:

input

stream:

1) ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用

2) StringBufferInputStream:把一个String对象作为InputStream

3) FileInputStream:把一个文件作为InputStream,实现对文件的读取操作

4) PipedInputStream:实现了pipe的概念,主要在线程中使用

5) SequenceInputStream:把多个InputStream合并为一个InputStream

Out

stream

1) ByteArrayOutputStream:把信息存入内存中的一个缓冲区中

2) FileOutputStream:把信息存入文件中

3) PipedOutputStream:实现了pipe的概念,主要在线程中使用

4) SequenceOutputStream:把多个OutStream合并为一个OutStream

1.2 以Unicode字符为导向的stream

以Unicode字符为导向的stream,表示以Unicode字符为单位从stream中读取或往stream中写入信息。以Unicode字符为导向的stream包括下面几种类型:

Input

Stream

1) CharArrayReader:与ByteArrayInputStream对应

2) StringReader:与StringBufferInputStream对应

3) FileReader:与FileInputStream对应

4) PipedReader:与PipedInputStream对应

Out

Stream

1) CharArrayWrite:与ByteArrayOutputStream对应

2) StringWrite:无与之对应的以字节为导向的stream

3) FileWrite:与FileOutputStream对应

4) PipedWrite:与PipedOutputStream对应

以字符为导向的stream基本上对有与之相对应的以字节为导向的stream。两个对应类实现的功能相同,字是在操作时的导向不同。如 CharArrayReader:和ByteArrayInputStream的作用都是把内存中的一个缓冲区作为InputStream使用,所不同的 是前者每次从内存中读取一个字节的信息,而后者每次从内存中读取一个字符。

1.3 两种不现导向的stream之间的转换

InputStreamReader和OutputStreamReader:把一个以字节为导向的stream转换成一个以字符为导向的stream。

2. stream添加属性

2.1 “为stream添加属性”的作用

运用上面介绍的Java中操作IO的API,我们就可完成我们想完成的任何操作了。但通过FilterInputStream和FilterOutStream的子类,我们可以为stream添加属性。下面以一个例子来说明这种功能的作用。

如果我们要往一个文件中写入数据,我们可以这样操作:

FileOutStream fs = new FileOutStream(“test.txt”);

然后就可以通过产生的fs对象调用write()函数来往test.txt文件中写入数据了。但是,如果我们想实现“先把要写入文件的数据先缓存到内存 中,再把缓存中的数据写入文件中”的功能时,上面的API就没有一个能满足我们的需求了。但是通过FilterInputStream和 FilterOutStream的子类,为FileOutStream添加我们所需要的功能。

2.2 FilterInputStream的各种类型

2.2.1 用于封装以字节为导向的InputStream

1) DataInputStream:从stream中读取基本类型(int、char等)数据。

2) BufferedInputStream:使用缓冲区

3) LineNumberInputStream:会记录input stream内的行数,然后可以调用getLineNumber()和setLineNumber(int)

4) PushbackInputStream:很少用到,一般用于编译器开发

2.2.2 用于封装以字符为导向的InputStream

1) 没有与DataInputStream对应的类。除非在要使用readLine()时改用BufferedReader,否则使用DataInputStream

2) BufferedReader:与BufferedInputStream对应

3) LineNumberReader:与LineNumberInputStream对应

4) PushBackReader:与PushbackInputStream对应

2.3 FilterOutStream的各种类型

2.2.3 用于封装以字节为导向的OutputStream

1) DataIOutStream:往stream中输出基本类型(int、char等)数据。

2) BufferedOutStream:使用缓冲区

3) PrintStream:产生格式化输出

2.2.4 用于封装以字符为导向的OutputStream

1) BufferedWrite:与对应

2) PrintWrite:与对应

3. RandomAccessFile

1) 可通过RandomAccessFile对象完成对文件的读写操作

2) 在产生一个对象时,可指明要打开的文件的性质:r,只读;w,只写;rw可读写

3) 可以直接跳到文件中指定的位置

4. I/O应用的一个例子

java 代码

import java.io.*; 
public class TestIO{ 
public static void main(String[] args) 
throws IOException{ 
//1.以行为单位从一个文件读取数据 
BufferedReader in = new BufferedReader( 
new FileReader("F:\\nepalon\\TestIO.java")); 
String s, s2 = new String(); 
while((s = in.readLine()) != null) 
s2 += s + "\n"; 
in.close(); 
//1b. 接收键盘的输入 
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); 
System.out.println("Enter a line:"); 
System.out.println(stdin.readLine()); 
//2. 从一个String对象中读取数据 
StringReader in2 = new StringReader(s2); 
int c; 
while((c = in2.read()) != -1) 
System.out.println((char)c); 
in2.close(); 
//3. 从内存取出格式化输入 
try{ 
DataInputStream in3 =new DataInputStream(new ByteArrayInputStream(s2.getBytes())); 
while(true) 
System.out.println((char)in3.readByte()); 

catch(EOFException e){ 
System.out.println("End of stream"); 

//4. 输出到文件 
try{ 
BufferedReader in4 =new BufferedReader(new StringReader(s2)); 
PrintWriter out1 =new PrintWriter(new BufferedWriter(new FileWriter("F:\\nepalon\\ TestIO.out"))); 
int lineCount = 1; 
while((s = in4.readLine()) != null) 
out1.println(lineCount++ + ":" + s); 
out1.close(); 
in4.close(); 

catch(EOFException ex){ 
System.out.println("End of stream"); 

//5. 数据的存储和恢复 
try{ 
DataOutputStream out2 =new DataOutputStream(new BufferedOutputStream( 
new FileOutputStream("F:\\nepalon\\ Data.txt"))); 
out2.writeDouble(3.1415926); 
out2.writeChars("\nThas was pi:writeChars\n"); 
out2.writeBytes("Thas was pi:writeByte\n"); 
out2.close(); 
DataInputStream in5 =new DataInputStream( 
new BufferedInputStream(new FileInputStream("F:\\nepalon\\ Data.txt"))); 
BufferedReader in5br =new BufferedReader(new InputStreamReader(in5)); 
System.out.println(in5.readDouble()); 
System.out.println(in5br.readLine()); 
System.out.println(in5br.readLine()); 

catch(EOFException e){ 
System.out.println("End of stream"); 

//6. 通过RandomAccessFile操作文件 
RandomAccessFile rf = new RandomAccessFile("F:\\nepalon\\ rtest.dat", "rw"); 
for(int i=0; i <10; i++) 
rf.writeDouble(i*1.414); 
rf.close(); 
rf = new RandomAccessFile("F:\\nepalon\\ rtest.dat", "r"); 
for(int i=0; i <10; i++) 
System.out.println("Value " + i + ":" + rf.readDouble()); 
rf.close(); 
rf = new RandomAccessFile("F:\\nepalon\\ rtest.dat", "rw"); 
rf.seek(5*8); 
rf.writeDouble(47.0001); 
rf.close(); 
rf = new RandomAccessFile("F:\\nepalon\\ rtest.dat", "r"); 
for(int i=0; i <10; i++) 
System.out.println("Value " + i + ":" + rf.readDouble()); 
rf.close(); 

}  

关于代码的解释(以区为单位):

1区中,当读取文件时,先把文件内容读到缓存中,当调用in.readLine()时,再从缓存中以字符的方式读取数据(以下简称“缓存字节读取方式”)。

1b区中,由于想以缓存字节读取方式从标准IO(键盘)中读取数据,所以要先把标准IO(System.in)转换成字符导向的stream,再进行BufferedReader封装。

2区中,要以字符的形式从一个String对象中读取数据,所以要产生一个StringReader类型的stream。



本文转自sucre03 51CTO博客,原文链接:http://blog.51cto.com/sucre/416698,如需转载请自行联系原作者


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/256464.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第9章 接口

1、抽象类&#xff1a; 包含抽象方法的类叫抽象类&#xff0c;如果一个类包含一个或多个抽象方法(abstract void f();)&#xff0c;该类必须被限定为抽象的&#xff0c;否则编译出错。 1、抽象类不能被实例化&#xff0c;实例化的工作应该交由它的子类来完成&#xff0c;它只需…

用node-webkit(NW.js)创建桌面程序

以往写windows桌面程序需要用MFC、C#之类的技术&#xff0c;那么如果你只会web开发技术呢&#xff1f;或者说你有一个网站&#xff0c;但是你想把你的网站打包成一个桌面应用程序&#xff0c;该如何做呢&#xff1f; 答案就是用node-webkit这个开源框架&#xff0c;他封装了web…

一头扎进Node系列 - 目录

前言 本系列是属于初级教程。博主我也还只是一个node的新兵蛋子&#xff0c;想通过学习官网的API文档&#xff0c;慢慢的打好Node基础。当然后期这系列文档会慢慢完善&#xff0c;并且会添加一些项目实战中遇到的一些问题以及解决方案&#xff01;如果你也是初学者&#xff0c;…

ANSYS——“There is at least 1 small equation solver pivot term”问题的解决办法

目录 问题出现的原因 问题解决办法 1、根据提示对节点进行约束的添加

JAVA中几个常用的方法

类Object是类层次结构的根类&#xff0c;每一个类都使用Object作为超类&#xff0c;所有对象&#xff08;包括数组&#xff09;都实现这个类的方法。jdk1.5中&#xff0c;描述了该类中的11个方法 1.getClass public final Class<? extends Object> getClass() 返回一个对…

ANSYS——载荷的方向

目录 一、压力的方向(FORCE) 1、为正的情况 2、为负的情况 二、压强的方向(PRESSURE)

kindeditor用法简单介绍(转)

1&#xff0c;首先去官网下载http://www.kindsoft.net/ 2&#xff0c;解压之后如图所示&#xff1a; 由于本人做的是用的是JSP&#xff0c;所以ASP,PHP什么的就用不上了&#xff0c;直接把那些去掉然后将整个文件夹扔进Myeclipse&#xff0c;如图&#xff1a; 里面有个报错&am…

hadoop 分片与分块,map task和reduce task的理解

分块&#xff1a;Block HDFS存储系统中&#xff0c;引入了文件系统的分块概念&#xff08;block&#xff09;&#xff0c;块是存储的最小单位&#xff0c;HDFS定义其大小为64MB。与单磁盘文件系统相似&#xff0c;存储在 HDFS上的文件均存储为多个块&#xff0c;不同的是&#…

SOLIDWORKS——参数化建模

https://www.sohu.com/a/259742200_100042821 知识点&#xff1a;投影曲线、曲面填充、扫描、外观设置 建模步骤 1.先在工具——方程式里输入一个直径的变量A120 。 2.在前视基准面上草绘圆&#xff0c;画一条直径。直径等于变量A。 3.旋转&#xff0c;选择粉色区域。 4.上视…

Arch 常用工具

一、网络浏览pacman -S firefox firefox-i18n注&#xff1a;该命令中的前者为 Firefox 主程序,后者为语言包。pacman -S opera二、图像编辑pacman -S gimp #图像编辑软件首选 GIMPpacman -S inkscape #矢量图形编辑软件Inkscapepacman -S scrot #…

Androd安全——反编译技术完全解析

0&#xff0e;前言单纯从技术角度上来讲&#xff0c;掌握反编译功能确实是一项非常有用的技能。另外既然别人可以反编译程序&#xff0c;我们当然有理由应该对程序进行一定的保护&#xff0c;因此代码混淆也是我们必须要掌握的一项技术。看完此篇如果对代码混淆也感兴趣&#x…

python——shape 与reshape

转载自:https://blog.csdn.net/u010916338/article/details/84066369 shape()和reshape()都是数组array中的方法 numpy中reshape函数的三种常见相关用法 numpy.arange(n).reshape(a, b) 依次生成n个自然数&#xff0c;并且以a行b列的数组形式显示np.arange(16).reshape(2,…

误删了microsoft visual c++后如何正常运行matlab

误删了microsoft visual c后如何正常运行matlab 本人在卸载visual studio2013的时候&#xff0c;因为这个软件卸载的过程中出现一些问题&#xff0c;误将visual c当成VS的组件一同删除了。但是在打开matlab 时发现出错&#xff0c;matlab打开后会出现下面的界面。 出现这个问题…

iScreenLocker 3.1.8 安卓锁屏通知--苹果一样的体验

*软件介绍:苹果锁屏通知(iScreenLocker)是一款android上ios风格的锁屏软件。它颠覆安智通知设计&#xff0c;将原来状态栏的通知搬到锁屏界面上来&#xff0c;能够在桌面轻松收发短信,微博,微信等消息。它独有的消息唤醒功能。能使手机从待机界面唤醒而消耗非常少的电量。手指轻…

JSP慕课网阶段用户登录小例子(不用数据库)

getAttribute和setAttribute一起使用&#xff0c;而getParameter用于取得如request传来的参数。 Web是请求/响应架构的使用&#xff0c;而request和response就是在服务器端生成的相应的两个对象&#xff0c;request能够获取客户端传递的参数及相关的一些信息&#xff0c;而resp…

机器学习python——python基础

目录 1、常用库 2、shape与reshape&#xff0c;dtype 3、range、arange、linspace、logspace 4、数组的计算、切片 5、绘图基本设置 6.三维绘图 1、常用库 numpy、scipy、matplotlib、math 2、shape与reshape&#xff0c;dtype https://blog.csdn.net/qq_45769063/arti…

win10环境下如何给visual studio 2013永久配置opencv3.1.0环境

win10环境下如何给visual studio 2013永久配置opencv3.1.0环境 本人在给visual studio 2013配置opencv 环境下遇到过一些问题&#xff0c;比如配置不成功或者不能永久配置opencv环境。先将自己的配置经验分享于此&#xff0c;希望同道中的好友可以用上。 首先自行下载Visual s…

属性名、变量名与 内部关键字 重名 加

procedure TForm4.btn3Click(Sender: TObject); varMyQj: TQJson;MyPrinter: TPrinter; beginMyQj : TQJson.Create;tryMyPrinter.name : A号打印机;MyPrinter.status : enabled;MyPrinter.&type : yes;MyQj.FromRecord<TPrinter>(MyPrinter);Memo1.Lines.Add(MyQj.A…

机器学习——支持向量机SVM之线性模型

目录 一、没有免费的午餐定理 二、支持向量机SVM&#xff08;support vector machine&#xff09; 1、线性模型和非线性模型 2、如何在线性模型中画出一条直线&#xff08;优化过程——vplink&#xff09; 1&#xff09;多少条&#xff1f; 2&#xff09;如何画出最好的直…

Oauth2.0和1.0区别

1.0的授权分3步, A)客户端到授权服务器请求一个授权令牌(request token&secret) B)引导用户到授权服务器请求授权 C)用访问令牌到授权服务器换取访问令牌(access token&secret) D)用访问令牌去访问得到授权的资源 2.0的用户授权过程有2步&#xff0c; A)引导用户到授权…