Java IO讲解----InputStream
第一次写博客,错误的地方还请大家提出来!
最近学到IO流,总结了一下自己对IO的理解,跟大家分享一下。
“在Java API中,可以从其中读入一个字节序列的对象成为输入流,而可以像其中下午一个字节序列的对象成为输出流。这些字节序列的来源地和目的地可以是文件,而且通常是
文件,但也可以是网络连接,甚至是内存块。抽象类InputStream和OutputStream构成了有层次结构的输入/输出(I/O)类的基础。
因为面向字节流不便于以Unicode形式(回忆一下,Unicode中每个字符都使用了多个字节来表示)存储信息,所以抽象类Reader和Writer类继承出来的专门用于处理Unicode字符的类构成了一个单独的层次结构,这些类拥有的读入和写出操作都是基于两字节的Unicode码元的,而不是基于单字节的字符。”
以上文字摘自《Java核心技术卷2:高级基础》
以上介绍主要想说明一件事,也是在学习java I/O流之前要搞明白的一件事:"Java I/O流分为面向字节流和面向字符流;面向字符流是基于面向字节流的,内部处理还是使用字节流来处理的。无非就是把那些繁琐的过程封装起来使我们使用方便,因为我们大多时候处理的还是字符串的处理。
今天主要介绍InputStream,介绍之前先把自己画的InputStream及其子类的构造图贴出来。

先介绍一个InputStream的API
abstract int read() 从数据中读入一个字节,并返回该字节。在碰到流的结尾时返回-1
int read(byte[] b)
读入一个字节数组,并返回实际读入的字节数,或者在碰到流的结尾时返回-1,这个方法最多读取b.length个字节。
int read(byte[] b,int off,int len)
读入一个字节数组,并返回实际读取的字节数,或者在碰到流的结尾时返回-1;
参数:
b:数据读入的数组
off第一个读入字节应该被放置的位置在b中的偏移量
len读入的字节的最大数量
long skip(long n)
在输入流中跳过n个字节,返回实际跳过的字节数(如果碰到流的结尾时则可能小于n)
int available()
返回在不阻塞的情况下可用的字节数
void close()
关闭这个流
void mark(int readlimit)
在当前输入流的位置打一个标记(并非所有流都支持这个特性)。如果从输入流中已经读入的字节多于readlimit个,则这个流允许忽略这个标记
void reset()
返回到最后的标记,随后对read的调用讲重新读入这些字节。如果当前没有任何标记,则这个流不被重置。
boolean markSupported()
如果这个流支持打标记,则返回true.
好了知识点都讲了,下面上Demo
一个读取文件的demo
1 package io; 2 3 import java.io.FileInputStream; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.io.OutputStream; 8 9 /** 10 * 输入流测试 读取文件测试 11 * 12 * @author Art_Craft 13 * 14 */ 15 public class InputStreamDemo { 16 public static void main(String[] args) { 17 try { 18 OutputStream out = new FileOutputStream("demo.dat"); 19 // 向文件中写入ABC三个字符 20 out.write('A'); 21 out.write('B'); 22 out.write('C'); 23 // 向文件中写入0x7fffffff (int类型的最大整数) 24 int n = 0x7fffffff; 25 out.write(n >>> 24); 26 out.write(n >>> 16); 27 out.write(n >>> 8); 28 out.write(n >>> 0); 29 // 向文件中写入'中' 30 out.write('中' >>> 8); 31 out.write('中' >>> 0); 32 out.close(); 33 /*详解说明上述操作的过程 34 * out.write(int)写入的的时候将整数的 “低八位” 写入到文件中,同时指针自动移动到下一个位置,准备再次写入 35 * 'A' 'B' 'C'属于字符,字符类型在java中占两个字节; 36 * 正常操作的话应该先对 'A' 'B' 'C'三个字符进行分割操作,按照高位在前的模式写出 37 * 但是我们知道'A' 'B' 'C' 所对应的int值前三个字节都为 0 所以就没必要再进行分割操作。直接写入,wrtie()方法直接取'A''B''C'的低八位 38 * 也就是最后一个字节,写入文件中,这样写方便了操作和节省了空间 39 * 当然你也可以为了保持一致 这样写 out.write('A'>>>8);out.write('A'>>>0) 这样写入'A'。不过前一个字节是空的,但是也占了一个字节 40 * 41 * 在写入0x7fffffff时 42 * 43 * 7f ff ff ff 44 * n>>>24 =00 00 00 7f 取 低八位 向文件中写入 7f 45 * n>>>16 =00 00 7f 00 取 低八位 向文件中写入 ff 46 * n>>>8 =00 7f ff ff ……………………………………ff 47 * n>>>0 =7f ff ff ff ……………………………………ff 48 * 这样就依次写入写入了 7f ff ff ff 49 * 50 * 同理'中'写入的过程也是一样 51 * 52 * 在java中所有的值都按照 高位在前 的模式写出 53 */ 54 55 //上述操作中已经向"demo.dat"文件中写入了ABC 0x7fffffff 中现在开始读取 56 InputStream in = new FileInputStream("demo.dat"); // FileInputStream用于对文件的输入流 57 //取回 A B C 58 char a=(char)in.read(); 59 char b=(char)in.read(); 60 char c=(char)in.read(); 61 System.out.println(a+" "+b+" "+c);//输出 A B C 62 63 //还原 0x7fffffff 64 int num=in.read()<<24;// 7f 00 00 00 65 num=num|in.read()<<16;// 7f 00 00 00|00 ff 00 00 =7f ff 00 00 66 num=num|in.read()<<8; // 7f ff 00 00|00 00 ff 00 =7f ff ff 00 67 num=num|in.read()<<0;// 7f ff ff 00|00 00 00 ff =7f ff ff ff 68 //这样一个int类型的数就还原出来了 69 System.out.println(Integer.toHexString(num));//输出 7fffffff 70 71 //还原'中' 72 int ch=in.read()<<8; 73 ch=ch|in.read()<<0; 74 System.out.println((char)ch);//输出 '中' 75 76 77 System.out.println(in.available());//输出 0 说明已经读完所有的字节 78 } catch (IOException e) { 79 e.printStackTrace(); 80 } catch (Exception e) { 81 e.printStackTrace(); 82 } 83 } 84 }
从上面操作可以看出一个使用字节流读取文件还是很繁琐的。你要读取一个文件化首先要明白它的存储过程。
posted on 2012-05-26 20:10 Arts&Crafts 阅读(373) 评论(0) 收藏 举报
浙公网安备 33010602011771号