基础第一篇之输入流inputstream
来源:互联网 发布:淘宝联盟认证怎么弄 编辑:程序博客网 时间:2024/06/06 03:58
作为打基础的第一篇,将从多个方面来解析inputstream。希望能给您一点帮助。
先上两段代码,根据这两段代码来分析。
一、字节流读取数据
FileInputStream fileInputStream = new FileInputStream("C:\\Users\\82024\\Desktop\\linux.txt"); byte[] b = new byte[1024]; int i; while((i=fileInputStream.read(b))!=-1) { String content = new String(b); System.out.println(content); }
注意:我在写的时候用的throws,关于throw,throws和try…catch,文末放链接。
1、先说说读取数据的过程
首先需要知道文件的路径,这时文件在硬盘中,需要读到内存中进行操作,所以你就派fileinputstream作先头部队,去找到这个文件,并以流的形式请到内存中。多提一句:计算机中所有对程序的操作都是在内存中。而计算机又只认识0和1,所以是以字节形式读的,那一个一个读太慢了,定义一个字节数组byte一读一个组,这样就方便一些。怎么知道它读取结束了呢,计算机当然不知道,所以设置了一个标志-1,当读到-1时,计算机就不读了。String对象,只是将读取的字节变成了字符串,显示在屏幕上看的。
2、详解inputstream
在java中,想知道一个类的作用,必然要看源码的。看源码能让思路更加清晰。
/** * 所有字节输入流实现类的基类 */public abstract class SInputStream { // 缓存区字节数组最大值 private static final int MAX_SKIP_BUFFER_SIZE = 2048; // 从输入流中读取数据的下一个字节,以int返回 public abstract int read() throws IOException; // 从输入流中读取数据的一定数量字节,并存储在缓存数组b public int read(byte b[]) throws IOException { return read(b, 0, b.length); } // 从输入流中读取数据最多len个字节,并存储在缓存数组b public int read(byte b[], int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); } else if (off < 0 || len < 0 || len > b.length - off) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } 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; } // 跳过输入流中数据的n个字节 public long skip(long n) throws IOException { long remaining = n; int nr; if (n <= 0) { return 0; } int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining); byte[] skipBuffer = new byte[size]; while (remaining > 0) { nr = read(skipBuffer, 0, (int)Math.min(size, remaining)); if (nr < 0) { break; } remaining -= nr; } return n - remaining; } // 返回下一个方法调用能不受阻塞地从此读取(或者跳过)的估计字节数 public int available() throws IOException { return 0; } // 关闭此输入流,并释放与其关联的所有资源 public void close() throws IOException {} // 在此输出流中标记当前位置 public synchronized void mark(int readlimit) {} // 将此流重新定位到最后一次对此输入流调用 mark 方法时的位置。 public synchronized void reset() throws IOException { throw new IOException("mark/reset not supported"); } // 测试此输入流是否支持 mark 和 reset 方法 public boolean markSupported() { return false; }}
(注:源码来自http://www.cnblogs.com/Alandre/p/4844241.html)
这个源码注释的比较清晰。首先inputstream是一个抽象类,所以inputstream取不到实例,也就是不能实例化。其次,inputstream下有几个方法,着重说下,抽象方法read(),read(byte b[]),read(byte b[], int off, int len)这三个方法:
(1)read():
抽象方法,也是inputstream读的基础.
(2)read(byte b[]):
这个方法就表示每次读取多少字节的数据。
(3)read(byte b[], int off, int len):
这个off是什么呢?就是读取字节时,数组的一个下标,白说就是说,我这次来的字节放在off这里,那我下次来的字节放在off+1这里。
这里还有一个点,就是最大的缓冲量为2048字节。
说完上面,说一个重要的问题,乱码问题:
乱码在我现在看到的有两点原因,第一点是编码问题,第二点就是上面这个程序的问题。我说说第二点,因为是以字节读取的数据,了解一下字节是有必要的。先简单说说,回来再写一个博客。
对于utf-8来说,英文和数字占一个字节,中文占2-4个字节,空格等符号占半个字节。所以明白了么。读取的数据,有时读得不完整,就导致了乱码。为了解决这个问题,就引入了字符流。计算机都是这样,一环套一环地去解决问题。
3、关于inputstream,fileinputstream
inpuntstream是objectinputstream,fileinputstreambyteaarrayinputstream的爸爸,是所有输入流的基类。作用的话,根据名字就可以看到,这里不多说。
二、字符流读取数据
先声明一点,其实字符流读取数据的根本也是字节流读取,只是封装了一遍。
FileInputStream fileInputStream = new FileInputStream("C:\\Users\\82024\\Desktop\\linux.txt"); StringBuffer buffer = new StringBuffer(); InputStreamReader reader = new InputStreamReader(fileInputStream,"gbk");//字节流和字符流的桥梁,根据环境来判断,要进行转换 BufferedReader bufferedReader = new BufferedReader(reader);//字符流的读取 String line; while((line=bufferedReader.readLine())!=null) { buffer.append(line); } if(bufferedReader!=null) { bufferedReader.close(); } String content = new String(buffer); System.out.println(content);
1、读取数据的过程
stringbuffer定义了一个缓冲区,通过inputstreamreader将字节转变为字符,bufferedreader.reader去读取字符放在缓冲区中,最后转为string输出。
2、inputsrteamreader是字节和字符的桥梁。
3、reader是bufferedreader,inputstreamreader,chararrayreader,filterreader等的基类。
4、关于关闭缓冲区的问题
关闭缓冲区是为了释放资源。缓冲区不手动关闭也是可以的,java中自动回收机制,但是这种机制,你不知道它什么会回收,不确定性太大。所以采取的手动关闭,能避免这种情况。
总结:基础还是很重要,看过了这些,觉得还要下更多功夫补回来。格物致知,方能不惑。能力有限,希望提建议。
参考博客:
http://www.cnblogs.com/Alandre/p/4844241.html
http://blog.csdn.net/cslucifer/article/details/76595449
http://www.cnblogs.com/sara-gcj/p/3307454.html
http://blog.csdn.net/zhao123h/article/details/52831524
http://blog.csdn.net/abc19900828/article/details/7889879
- 基础第一篇之输入流inputstream
- Java基础 InputStream输入流
- Java之字节输入流InputStream
- java输入流InputStream
- InputStream 输入流
- InputStream字符输入流
- 第一篇:JAVA之基础学习线路图
- XZ_Swift之Swift基础第一篇
- 我的Python第一篇 输入基础篇
- java IO 学习小结之输入流InputStream
- File类的基本操作之InputStream字节输入流
- File类的基本操作之InputStream字节输入流
- java io 学习小结之输入流InputStream
- Java学习笔记之IO(二):InputStream输入字节流
- InputStream(输入流)转换成多个InputStream(输入流)
- 字节输入流类InputStream
- 窥探Java输入流-InputStream
- InputStream输入流的方法
- 趣图:新出了一些有趣的动物技术书
- 17 天拿到 70 份面试,这个程序员是如何做的?
- 为Ubuntu 16.04 添加永久免费https SSL证书(解决python2.7
- 【树形dp】二叉苹果树
- 流程图解Spring Framework(六) Spring BeanPostProcessor如何工作的?
- 基础第一篇之输入流inputstream
- opencv(c++)-图像基本操作
- 面向对象:择一城终老,遇一人白首
- c#学习记录
- ArrayList动态扩容机制
- MD5+Salt加密
- 流程图解Spring Framework(七) Spring 如何创建代理的--jdk?
- 学习就是机会
- 《算法竞赛入门经典(第二版)》学习之路!