Java随笔(2)I/O流中InputStream/OutputStream
2016-12-28 18:19
525 查看
如有转载,请注意:
http://blog.csdn.net/wjzj000/article/details/53911635
本菜开源的一个自己写的Demo,希望能给Androider们有所帮助,水平有限,见谅见谅…
https://github.com/zhiaixinyang/PersonalCollect (拆解GitHub上的优秀框架于一体,全部拆离不含任何额外的库导入)
https://github.com/zhiaixinyang/MyFirstApp(Retrofit+RxJava+MVP)
所以今天自己就写篇博客记录自己学习的过程。
最近看到一篇写I/O的博客:
http://blog.csdn.net/smartbetter/article/details/51323904
这里借用他的一张图,增加增加门面…
1,字节数组。
2,String对象。
3,文件。
4,管道。
5,一个由其他种类的流组成的序列。
6,其他数据源,例网络获取…
每一种数据源都有对应的InputStream子类。
自己简单测试一个读取本地File的demo
关于FileReader
那么这里我们可以很自然的想到一个问题,Reader和InputStream有什么样的区别?
咱们在最开始的时候提过,一个是操作字符,一个是操作字节。
《Java编程思想》中提到了如下的区别:
有时我们需要把来自“字节”层次结构中的类和“字符”层次结构中的类结合起来使用。为了实现这个目的,要用到“适配器”类:InputStreamReader可以把InputStream转化成Reader,而OutputStreamWeiter可以把OutputStream转换为Writer。
其次设计Reader和Writer继承层次结构主要是为了国际化。老的I/O流继承层次结构仅支持8位的字节流,并且不能很好地处理16位的Unicode字符。由于Unicode用于字符国际化(Java本身的char也是16位的Unicode),所以添加Reader和Writer继承层级结构就是为了在所有的I/O操作中都支持Unicode。
Unicode:就是ISO嫌各国各种编码方式太多,就本着自愿的原则整了这么一套编码方式。
“字节”是一个8位的物理存贮单元,而“字符”则是一个文化相关的符号。在unicode中,一个字符就是两个字节。一个汉字算两个英文字符的时代已经快过去了。无论是半角的英文字母,还是全角的汉字,它们都是统一的”一个字符“!
UTF-8就是每次8个位传输数据,而UTF-16就是每次16个位。UTF-8就是在互联网上使用最广的一种unicode的实现方式,这是为传输而设计的编码,并使编码无国界,这样就可以显示全世界上所有文化的字符了。
这里我们可以看到效果中的不同,操作字节的时候我们将回车也一并读取。而字符操作的时候我们是通过回车来进行判断并且通过StringBuilder进行拼接。
最后希望各位看官可以star我的GitHub,三叩九拜,满地打滚求star:
https://github.com/zhiaixinyang/PersonalCollect
https://github.com/zhiaixinyang/MyFirstApp
http://blog.csdn.net/wjzj000/article/details/53911635
本菜开源的一个自己写的Demo,希望能给Androider们有所帮助,水平有限,见谅见谅…
https://github.com/zhiaixinyang/PersonalCollect (拆解GitHub上的优秀框架于一体,全部拆离不含任何额外的库导入)
https://github.com/zhiaixinyang/MyFirstApp(Retrofit+RxJava+MVP)
写在前面
操作File的次数多了,不免对流这个概念产生疑惑。时断时续的也找了不少的博客,但是看罢总觉着那个地方缺点什么。所以今天自己就写篇博客记录自己学习的过程。
最近看到一篇写I/O的博客:
http://blog.csdn.net/smartbetter/article/details/51323904
这里借用他的一张图,增加增加门面…
引子
InuputStream类型:
根据《Java编程思想》的介绍,InputStream的作用是用来表示那些从不同数据源产生输入的类。这些数据源主要包含如下6大类:1,字节数组。
2,String对象。
3,文件。
4,管道。
5,一个由其他种类的流组成的序列。
6,其他数据源,例网络获取…
每一种数据源都有对应的InputStream子类。
OutputStream类型:
该类别的类决定了输出的目标:字节数组,文件,管道。Reader和Writer:
简单来说InputStream/OutputStream相关的类用在面向字节;而Reader/Write相关的类用在面向字符。举个例子
缓冲输入文件:
打开一个文件用于字符输入,可以使用以String或File对象作为文件名的FileInputReader。为了提高速度,对文件进行缓冲,我们应将所产生的引用传给一个BufferedReader构造方法。BufferedReader也提供readLine()方法,所以这是我们最终的对象以及进行读取的接口。当readLine()返回null时,即可判断到达文件末尾。/** * BufferedReader的官方解释: * 创建使用指定大小的输入缓冲区的缓冲!字符!输入流。 */ BufferedReader br=new BufferedReader(new FileReader(fileName)); String s; StringBuilder sb=new StringBuilder(); while ((s=br.readLine())!=null){ sb.append(s); } br.close();
自己简单测试一个读取本地File的demo
public static void main(String[] args) { try { //关于FileReader,跳过代码就能看到解析 BufferedReader br=new BufferedReader(new FileReader(new File("E:\\test.txt"))); StringBuilder sb =new StringBuilder(); String lines; while((lines=br.readLine())!=null){ //因为有中文,所以使用utf-8编码格式。 //但是new String的时候要把字符串转成字节 lines=new String(lines.getBytes(),"utf-8"); sb.append(lines); } System.out.println(sb.toString()); } catch (IOException e) { e.printStackTrace(); } }
关于FileReader
//我们可以看到内部使用的就是一个FileInputStream public FileReader(File file) throws FileNotFoundException { super(new FileInputStream(file)); }
那么这里我们可以很自然的想到一个问题,Reader和InputStream有什么样的区别?
咱们在最开始的时候提过,一个是操作字符,一个是操作字节。
《Java编程思想》中提到了如下的区别:
有时我们需要把来自“字节”层次结构中的类和“字符”层次结构中的类结合起来使用。为了实现这个目的,要用到“适配器”类:InputStreamReader可以把InputStream转化成Reader,而OutputStreamWeiter可以把OutputStream转换为Writer。
其次设计Reader和Writer继承层次结构主要是为了国际化。老的I/O流继承层次结构仅支持8位的字节流,并且不能很好地处理16位的Unicode字符。由于Unicode用于字符国际化(Java本身的char也是16位的Unicode),所以添加Reader和Writer继承层级结构就是为了在所有的I/O操作中都支持Unicode。
Unicode:就是ISO嫌各国各种编码方式太多,就本着自愿的原则整了这么一套编码方式。
“字节”是一个8位的物理存贮单元,而“字符”则是一个文化相关的符号。在unicode中,一个字符就是两个字节。一个汉字算两个英文字符的时代已经快过去了。无论是半角的英文字母,还是全角的汉字,它们都是统一的”一个字符“!
UTF-8就是每次8个位传输数据,而UTF-16就是每次16个位。UTF-8就是在互联网上使用最广的一种unicode的实现方式,这是为传输而设计的编码,并使编码无国界,这样就可以显示全世界上所有文化的字符了。
让我们通过其他方式来了解其中的不同:
//接下来我们来走一遍操作字节 try { DataInputStream dis=new DataInputStream(new FileInputStream(new File("E:\\test.txt"))); int line; byte[] b=new byte[1024]; //下边我们来瞅一瞅,这个传入byte[]的read()重载方法。 while((line=dis.read(b))!=-1){ //把字节转成字符 System.out.println(new String(b,"utf-8")); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
//in就是我们在构造方法中传入的对应流对象 public final int read(byte b[]) throws IOException { return in.read(b, 0, b.length); } public int read(byte b[], int off, int len) throws IOException { //省略部分异常处理和判空的情况 int c = read(); if (c == -1) { return -1; } b[off] = (byte)c; int i = 1; try { for (; i < len ; i++) { c = read(); if (c == -1) { break; } b[off + i] = (byte)c; } } catch (IOException ee) { } return i; }
这里我们可以看到效果中的不同,操作字节的时候我们将回车也一并读取。而字符操作的时候我们是通过回车来进行判断并且通过StringBuilder进行拼接。
尾声
OK,关于流的用法就简单记录于此,以后有更吊的用法再回过来继续。最后希望各位看官可以star我的GitHub,三叩九拜,满地打滚求star:
https://github.com/zhiaixinyang/PersonalCollect
https://github.com/zhiaixinyang/MyFirstApp
相关文章推荐
- JAVA FILE or I/O学习 - I/O流操作:FileInputStream、FileOutputStream、ObjectInputStream、ObjectOutputStream、InputStreamReader、OutputStreamWriter等
- Java I/O流-BufferedInputStream、BufferedOutputStream
- Java I/O流InputStream,OutputStream,Reader,Writer
- Java I/O流-总结(InputStream,OutputStream,Reader,Writer)
- 转: java的InputStream和OutputStream的理解
- java的InputStream和OutputStream的理解
- java的InputStream和OutputStream的理解【转】
- I/O流的设计(Java的InputStream/OuputStream和Reader/Writer的C++实现)
- java I/O流,输入流,输出流,输入输出流,InputStream,FileInputStream,文件流,byte,url
- java的InputStream和OutputStream的理解
- java中使用ObjectOutputStream和ObjectInputStream时产生的“invalid stream header”错误解决方法
- java的InputStream和OutputStream的理解
- java的InputStream和OutputStream的理解
- Java ObjectInputStream与ObjectOutputStream阻塞(block)问题
- java inputStream ,outputStream
- Java文件读写数据流大全(InputStream、OutputStream、FileInpuStream)
- JAVA中InputStream和OutputStream如何区分
- java的InputStream和OutputStream的理解【转】
- Java.IO.InputStream-OutputStream
- I/O流的设计(Java的InputStream/OuputStream和Reader/Writer的C++实现)