????? 以前老师讲C++中的I/O机制时,听得似懂非懂,对什么字节流仅有一些浅显的认识。听胡哥讲了java中的I/0机制后,才对这些概念有了进一步的深入。
??? 首先,先介绍一些基本概念吧:
?? 字节(Byte)是计算机信息技术用于计量存储容量和传输容量的一种计量单位,1个字节等于8位二进制(8bit)
?? 在ASCII码中,一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字节的空间。
??? 注意:MiB和MB,KiB和KB等的区别:
?? 1KiB(kilobyte)=1024byte
?? 1KB(kibibyte)=1000byte
?? 1MiB(megabyte)=1048576byte
?? 1MB(mebibyte)=1000000byte
??? 基本数据类型与bit的关系如下表所示:?
short
16bit/2byte
int
32bit/4byte
long 64bit /8byte float32bit/4byte
?? 加入在记事本中写入数字123后,它的大小是3字节,而它所占的空间大小是4KB,为什么会是这样的结果呢???我觉得这应该和计算机内部的存储机制有关,具体为什么,等我查完相关的资料后,再来解答这个问题,言归正传,说说我们的I/0机制吧。
????? I/0机制正如平常所见的水龙头中的水流出来一样,有流出的水,亦有流进的水。水正如数据,水龙头就如数据所在的文件。java中的数据流按方向分为输入流和输出流。输入流是以InputStream抽象类为继承类的各个子类,输出流是以OutputStream抽象类为继承类的各个子类。InputStream是基于字节读取的输入流,InpuStream类中主要定义了以下几个方法:
1.int available():返回流中可读取的有效字节 长度;
2、int read():返回流中的下一个字节作为一部byte指,注意此方法返回虽为int型,实际上是从流中读取的一个byte值,即8bit;
3、int read(byte[]b)用于流中读到的byte数组
如果要从文件中读取数据,那么就要用到FileStream类了
具体的用法如下代码:?
class="java">public void ReadFile() { String FileName="c:\\deci.txt"; try { InputStream Ins=new FileInputStream(FileName); try { int byteCount=Ins.available(); // 获得输入文件的字节数 byte [] stringByte=new byte[byteCount]; //新建字节数组 Ins.read(stringByte); //读入数组 String readstr=new String(stringByte); //将字节数组转换为字符串 System.out.println(readstr); //输出读入文件的内容 Ins.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); }
???
?? 上面的例子仅仅使用于读取字节,加入我们要读入字符串,int,double,float这些数据对象呢,总不能又一个一个字节的读吧,这时我们就要用到另外一个输入类DataInputStream,具体用法如下:?
//读文件 public void ReadFile() { try{ //用DataInputStream类 InputStream is=new FileInputStream("testComputer.txt"); DataInputStream ios=new DataInputStream(is); //字符串读取时,先读取存储的长度,再读取其内容 byte Scount=ios.readByte(); //先读取其长度 System.out.println(Scount); byte [] rts=new byte[Scount]; //读取内容 ios.read(rts); String aa=new String(rts); System.out.println(aa); byte sscount= ios.readByte(); //与上面类似 byte[]rsp=new byte[sscount]; ios.read(rsp); String bb=new String(rsp); System.out.println(bb); byte a=ios.readByte(); //读取存储的byte System.out.println(a); int count=ios.readInt(); //读取存储的int System.out.println(count); double sell=ios.readDouble(); //读取存储的double System.out.println(sell); ios.close(); } catch(Exception e) { e.printStackTrace(); } } ??
?? 介绍完了输入流之后,接下来介绍我们的输出流OutputStream,OutputSteam主要定义了以下几个方法:
1、void close():关闭流,与输入流类似;
2、void flush():强制输出到目标中
3、void write(byte[]b):将byte数组中的内容输出到流中:
具体用法如下:
public void WriteFile(String str) { String FileName="WriteFile.txt"; //文件路径为当前文件的库文件 try { OutputStream os=new FileOutputStream(FileName); byte[] WriteByte=str.getBytes(); try { os.write(WriteByte); os.flush(); //强制写出 os.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
类似的道理:如果要将int,double等数据写进文件,就需要用到DataOutputStream类了,具体用法如下:
//写入文件操作 public void testWrite(Computer cp) { try{ //先写入文件 OutputStream os=new FileOutputStream("testComputer.txt"); DataOutputStream dos=new DataOutputStream(os); //对于字符串而言,先存储其长度,再存储字节数组 int len=cp.type.length(); byte [] ts=cp.type.getBytes(); //存储字符串时,可有意识地对字符串进行一系列操作,对数据加密,但注意读取时,要先消去相应的操作 dos.writeByte(len); dos.write(ts); //对于字符串而言,先存储其长度,再存储字节数组 int lens=cp.ProduceDate.length(); byte[] sp=cp.ProduceDate.getBytes(); dos.writeByte(lens); dos.write(sp); //存入其他类型的变量 dos.writeByte(cp.ProduceCount); //写入byte dos.writeInt(cp.SellCount); //写入int //注意查看源代码自己写相应函数 dos.writeDouble(cp.YunXing); //写入double //刷新,关闭 dos.flush(); dos.close(); } catch(Exception e) { e.printStackTrace(); } }
?
?
?
?