十分钟学会Java io

JAVAIO装饰者模式:

不知道大家在学JAVA IO的时候,有没有被各种五花八门的构造函数之间的组合和嵌套弄得头昏脑涨,比如BufferedReaderbr=newBufferedReader(newInputStreamReader

(newFileInputStream(filename),"UTF-8"));与其去记这些函数,不如来看下面一段话。

先来看一幅图:

这是一个简单的JAVA输入输出流的类层次结构图。

我们知道,Reader类InputStream类是不能直接被实例化的,只能实例其子类(或其子类的子类…),Reader类和InputStream类里只封装了一些IO所必须的抽象方法,具体实现和怎么实现则直接由其子类所定义,这些直接子类分别直接搭建了从文件到程序的管道(不同子类有不同管道),管道里面就是具体的流,而这些子类派生出来的子类则对这些管道进行了改进,或直接对管道本身进行改良,或在管道和程序之间再架设一个缓冲区,这就是JAVA IO的装饰者模式。

再来看上面的代码,最里面的newFileInputStream(filename)搭建了一个从文件到程序的管道,第一个参数是文件名,可以是像“test.txt”这样的相对路径(这样文件就存放在工程根目录下),也可以是像”E:\JAVA Src\homework“这样的绝对路径,不过推荐使用相对路径,一来方便本机文件的管理,二来方便移植给别人。 再来看次外层的newInputStreamReader

(newFileInputStream(filename),"UTF-8"),先说说第二个参数,设置字符集,一般设置为“UTF-8‘,为国际通用标准,至于第一个参数,先看一下InputStreamReader的构造函数,

这里我们用的是第四个构造函数,它的第一个参数为一个InputStream对象,而我们传入的是FileInputStream,这里使用了多态技术,莫方,问题不大,关于多态只需要记住下面这句话,“多态的核心:父类引用可以指向子类的对象。“,从上面的继承树可以看出FileInputStream类正是InputStream类的子类,而调用时,InputStream in = new FileInputStream(filename),等号后面是我们传入的子类对象,等号前面是一个父类的应用,所以,多态没问题了吧?再从宏观上来看,newInputStreamReader

(newFileInputStream(filename),"UTF-8"),把一个字节流转换成了字符流,对管道本身做改良:把运字节的管道改成了运字符的管道,这就是JAVA IO修饰者模式的体现。 再来看最外层的BufferedReader br=newBufferedReader(newInputStreamReader

(newFileInputStream(filename),"UTF-8")),分析方法同次外层,这里在管道和程序之间又架设了一个缓冲区,也是JAVA IO修饰者模式的体现。

所以,这些东西都不用记了,使用的时候查JAVA API就行。

在此附上一个无毒无害的JAVA 在线API工具

http://tool.oschina.net/apidocs/apidoc?api=jdk_7u4

封装一个JAVA IO操作工具

在学io的时候,经常遇到读写数字和字符串的,比如从一大堆包含数字和字符串的txt文件里提取数字,,里面还有各种不可见字符…,我的思路是,写的时候全部把数据转成字符串,然后利用字符流再写,读的时候用字符流读,再利用String类强大的API进行数据分割(其实在JAVA高编里有现成的正则表达式可以了解下,限于学习成本,这里直接用自己设计的模型)

//做下说明

/**

* 在大多数编程语言中,从键盘上输入的回车等效于两个字符'\r'+'\n'

* 'r':回到行首;'n':新起一行

* 这里把content设置成这样是为了模拟文本编辑中换行操作

* 以及字符串和数字混合和分割的问题

*/

利用这样一段代码把它写到文本文档里:

Stringcontent="中南大学\r\n通信工程1602班\r\n100023";

Stringfilename="test.txt";

writefile(content,filename);

}

publicstaticvoidwritefile(Stringcontent,Stringfilename)throwsException {

FileOutputStreamfos=newFileOutputStream(filename);

OutputStreamWriterosw=newOutputStreamWriter(fos,"UTF-8");

BufferedWriterbw=newBufferedWriter(osw);

bw.write(content);

bw.close();

osw.close();

fos.close();

}

(说明一下为什么吧writefile()设置成static静态, main()函数是静态的,在静态方法里只能调用静态方法或变量,如果不设置成static,这样调用也行;:new“YourClassName”().writefile(content,filename)

打开txt文档,如下

下面再来看读的操作,根据一个文件名读取,并返回一个字符串

publicstaticString readfile(Stringfilename)throwsException{//原样读取

BufferedReaderbr=newBufferedReader(newInputStreamReader

(newFileInputStream(filename),"UTF-8"));

StringBufferlines=newStringBuffer();

/**

*StringBuffer是一个动态字符串类,常用此类对象的append()方法来链接字符串

*其实也可以用String类的”+“代替,但是前者性能明显优于后者

*最后要用StringBuffer类的toString()方法转成String

*这样才能使用String类强大而灵活的API

*/

intcount= 0;

while((count=br.read())!=-1){

//read方法返回一个整数,用(char)转为字符

lines.append((char)count);

}

br.close();

returnlines.toString();

}

输出打印如下

然后提取数字

publicstaticArrayList getNumbers(Stringcontent) {

StringBufferaNumber=newStringBuffer();

ArrayListNumbers=newArrayList();;

for(inti= 0;i

charch=content.charAt(i);

while(ch>='0'&&ch

aNumber.append(ch);

i++;

if(i==content.length())break;

ch=content.charAt(i);

}

if(aNumber.length()>0) {

Numbers.add(Integer.parseInt(aNumber.toString()));

aNumber.delete(0,aNumber.length());

}

}

returnNumbers;

}

提取字符串等其他操作类似,只要改一下判断条件就行。

觉得写得不错,请点个赞,关注一下。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180410A0N0G700?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券