java IO(三):数据操作流、合并流、回退流、对象序列化、字符编码问题、压缩流
来源:互联网 发布:hbase查找数据方式 编辑:程序博客网 时间:2024/06/05 06:29
数据操作流
在io包中,提供了两个与平台无关的数据操作流:
- 数据输入流(DataInputStream)
- 数据输出流(DataOutputStream)
DataOutputStream接口定义了一系列的writeXxx()的操作,可以写入各种数据类型的数据。
范例:使用数据操作流写入 与 读出数据
import java.io.DataOutputStream ;import java.io.File ;import java.io.FileOutputStream ;public class DataOutputStreamDemo{public static void main(String args[]) throws Exception{// 所有异常抛出DataOutputStream dos = null ;// 声明数据输出流对象File f = new File("d:" + File.separator + "order.txt") ; // 文件的保存路径dos = new DataOutputStream(new FileOutputStream(f)) ;// 实例化数据输出流对象String names[] = {"衬衣","手套","围巾"} ;// 商品名称float prices[] = {98.3f,30.3f,50.5f} ;// 商品价格int nums[] = {3,2,1} ;// 商品数量for(int i=0;i<names.length;i++){// 循环输出dos.writeChars(names[i]) ;// 写入字符串dos.writeChar('\t') ;// 写入分隔符dos.writeFloat(prices[i]) ; // 写入价格dos.writeChar('\t') ;// 写入分隔符dos.writeInt(nums[i]) ; // 写入数量dos.writeChar('\n') ;// 换行}dos.close() ;// 关闭输出流}};
import java.io.DataInputStream ;import java.io.File ;import java.io.FileInputStream ;public class DataInputStreamDemo{public static void main(String args[]) throws Exception{// 所有异常抛出DataInputStream dis = null ;// 声明数据输入流对象File f = new File("d:" + File.separator + "order.txt") ; // 文件的保存路径dis = new DataInputStream(new FileInputStream(f)) ;// 实例化数据输入流对象String name = null ;// 接收名称float price = 0.0f ;// 接收价格int num = 0 ;// 接收数量char temp[] = null ;// 接收商品名称int len = 0 ;// 保存读取数据的个数char c = 0 ;// '\u0000'try{while(true){temp = new char[200] ;// 开辟空间len = 0 ;while((c=dis.readChar())!='\t'){// 接收内容temp[len] = c ;len ++ ;// 读取长度加1}name = new String(temp,0,len) ;// 将字符数组变为Stringprice = dis.readFloat() ;// 读取价格dis.readChar() ;// 读取\tnum = dis.readInt() ;// 读取intdis.readChar() ;// 读取\nSystem.out.printf("名称:%s;价格:%5.2f;数量:%d\n",name,price,num) ;}}catch(Exception e){}dis.close() ;}};
合并流
从概念上讲就是把内容合并在一起了。
使用范例:
import java.io.File ;import java.io.SequenceInputStream ;import java.io.FileInputStream ;import java.io.InputStream ;import java.io.FileOutputStream ;import java.io.OutputStream ;public class SequenceDemo{public static void main(String args[]) throws Exception {// 所有异常抛出InputStream is1 = null ;// 输入流1InputStream is2 = null ;// 输入流1OutputStream os = null ;// 输出流SequenceInputStream sis = null ;// 合并流is1 = new FileInputStream("d:" + File.separator + "a.txt") ;is2 = new FileInputStream("d:" + File.separator + "b.txt") ;os = new FileOutputStream("d:" + File.separator + "ab.txt") ;sis = new SequenceInputStream(is1,is2) ;// 实例化合并流int temp = 0 ;// 接收内容while((temp=sis.read())!=-1){// 循环输出os.write(temp) ;// 保存内容}sis.close() ;// 关闭合并流is1.close() ;// 关闭输入流1`is2.close() ;// 关闭输入流2os.close() ;// 关闭输出流}};
回退流
在Java IO中所有的数据都是采用顺序读取的方式,如果在输入流中某个不需要的数据被读取进来,则只能通过程序将这些数据处理掉,为了解决这样的读取问题,在java中提供了一种回退输入流(PushbackInputStream、PushbackReader),可以把读取进来的某些数据退回到输入流的缓冲区之中。
操作机制:
回退操作包括字节流和字符流,这里讲诉字节流。
PushbackInputStream类常用方法:
对于回退操作来说,针对InputStream的三个read()方法,回退流使用了三个unRead()方法,分别与之对应。
范例:在内存中使用ByteArrayInputStream作为输入流
import java.io.ByteArrayInputStream ;import java.io.PushbackInputStream ;public class PushInputStreamDemo{ publicstatic void main(String args[]) throws Exception { // 所有异常抛出 Stringstr = "www.mldnjava.cn" ; //定义字符串 PushbackInputStreampush = null ; // 定义回退流对象 ByteArrayInputStreambai = null ; // 定义内存输入流 bai= new ByteArrayInputStream(str.getBytes()) ; //实例化内存输入流 push= new PushbackInputStream(bai) ; //从内存中读取数据 System.out.print("读取之后的数据为:"); inttemp = 0 ; while((temp=push.read())!=-1){ // 读取内容 if(temp=='.'){ // 判断是否读取到了“.” push.unread(temp); // 放回到缓冲区之中 temp= push.read() ; // 再读一遍 System.out.print("(退回"+(char)temp+")") ; }else{ System.out.print((char)temp); // 输出内容 } } }};
对象序列化
对象序列化就是把对象变为二进制数据流的一种方法,通过对象的序列化可以方便的实现对象的传输或储存。
如果一个类想支持初始化,则该类必须实现java.io.Serilizable接口。该接口定义如下:
publicinterface Serilizable{ }
该接口中不存在方法,因此该类属于一个标示接口,表示实现该的接口的类具备某种能力。
1. 对象的序列化与反序列化
2. serialVersionUID
在序列化的操作中引入了一个serialVersionUID常量,可以通过此常量来验证版本的一致性,在进行反序列化的时候,JVM会把传进来的字节流中的serialVersionUID与本地对应类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。
import java.io.Serializable ;public class Person implementsSerializable{ privateString name ; // 声明name属性,但是此属性不被序列化 privateint age ; // 声明age属性 publicPerson(String name,int age){ // 通过构造设置内容 this.name= name ; this.age= age ; } publicString toString(){ // 覆写toString()方法 return"姓名:" + this.name + ";年龄:" + this.age; }};
3. 对象输出流:ObjectOutputStream
一个对象要想进行输出,就必须使用ObjectOutputStream类,该类定义如下
importjava.io.File ;importjava.io.FileOutputStream ;importjava.io.OutputStream ;importjava.io.ObjectOutputStream ;publicclass SerDemo01{public static void main(String args[]) throwsException { File f = new File("D:" +File.separator + "test.txt") ; //定义保存路径 ObjectOutputStream oos = null ; // 声明对象输出流 OutputStream out = newFileOutputStream(f) ; // 文件输出流 oos = new ObjectOutputStream(out) ; oos.writeObject(new Person("张三",30)); // 保存对象 oos.close() ; // 关闭}};
到底序列化了哪些东西呢?
所有对象各自拥有各自的属性值,但是所有的方法都是公共的,所以序列化对象的时候实际上序列化的就是属性。
4. 对象输入流:ObjectInputStream
importjava.io.File ;importjava.io.FileInputStream ;importjava.io.InputStream ;importjava.io.ObjectInputStream ;publicclass SerDemo02{public static void main(String args[]) throwsException { File f = new File("D:" +File.separator + "test.txt") ; //定义保存路径 ObjectInputStream ois = null ; // 声明对象输入流 InputStream input = newFileInputStream(f) ; // 文件输入流 ois = new ObjectInputStream(input) ; // 实例化对象输入流 Object obj = ois.readObject() ; // 读取对象 ois.close() ; // 关闭 System.out.println(obj) ;}};
5. transient关键字
当使用Serializiable接口实现序列化操作的时候,如果一个对象中的某个属性不希望被序列化的话,则可以使用transient关键字进行声明。
import java.io.Serializable ;public class Person implementsSerializable{ privatetransient String name ; // 声明name属性,但是此属性不被序列化 privateint age ; // 声明age属性 publicPerson(String name,int age){ // 通过构造设置内容 this.name= name ; this.age= age ; } publicString toString(){ // 覆写toString()方法 return"姓名:" + this.name + ";年龄:" + this.age; }}; import java.io.File ;import java.io.IOException ;import java.io.FileOutputStream ;import java.io.OutputStream ;import java.io.ObjectOutputStream ;import java.io.FileInputStream ;import java.io.InputStream ;import java.io.ObjectInputStream ;public class SerDemo04{ publicstatic void main(String args[]) throws Exception{ ser(); dser(); } publicstatic void ser() throws Exception { Filef = new File("D:" + File.separator + "test.txt") ; // 定义保存路径 ObjectOutputStreamoos = null ; // 声明对象输出流 OutputStreamout = new FileOutputStream(f) ; // 文件输出流 oos= new ObjectOutputStream(out) ; oos.writeObject(newPerson("张三",30)) ; // 保存对象 oos.close(); // 关闭 } publicstatic void dser() throws Exception { Filef = new File("D:" + File.separator + "test.txt") ; // 定义保存路径 ObjectInputStreamois = null ; // 声明对象输入流 InputStreaminput = new FileInputStream(f) ; //文件输入流 ois= new ObjectInputStream(input) ; // 实例化对象输入流 Objectobj = ois.readObject() ; // 读取对象 ois.close(); // 关闭 System.out.println(obj); }};
可以看到在反序列化后,打印结果中name为输出null。
6. 序列化一组对象
对象输出时只提供了一个对象的输出操作(writeObject(Object obj)),并没有提供多个对象的输出,如果现在要对多个对象进行序列化的操作,则可以使用对象数组完成,由于数组是引用数据类型,所以可以直接使用Object类型进行接收。
importjava.io.File ;importjava.io.IOException ;importjava.io.FileOutputStream ;importjava.io.OutputStream ;importjava.io.ObjectOutputStream ;importjava.io.FileInputStream ;importjava.io.InputStream ;importjava.io.ObjectInputStream ;publicclass SerDemo05{public static void main(String args[]) throwsException{ Person per[] = {new Person("张三",30),newPerson("李四",31), new Person("王五",32)}; ser(per) ; Object o[] = (Object[])dser() ; for(int i=0;i<o.length;i++){ Person p = (Person)o[i] ; System.out.println(p) ; }}public static void ser(Object obj[]) throwsException { File f = new File("D:" +File.separator + "test.txt") ; //定义保存路径 ObjectOutputStream oos = null ; // 声明对象输出流 OutputStream out = new FileOutputStream(f); // 文件输出流 oos = new ObjectOutputStream(out) ; oos.writeObject(obj) ; // 保存对象 oos.close() ; // 关闭}public static Object[] dser() throws Exception{ File f = new File("D:" +File.separator + "test.txt") ; //定义保存路径 ObjectInputStream ois = null ; // 声明对象输入流 InputStream input = newFileInputStream(f) ; // 文件输入流 ois = new ObjectInputStream(input) ; // 实例化对象输入流 Object obj[] =(Object[])ois.readObject() ; // 读取对象 ois.close() ; // 关闭 return obj ;}};
数组能储存的对象数量有限,因此可以使用类集进行序列化的操作。
编码设置问题
编码:
乱码的产生:
得到本机的编码显示:
使用System类获取与本机系统相关的一些信息,使用如下方法
public static Properties getProperty()
System.out.println(“系统默认编码” +System.getProperty(“File.encoding”) );
范例:
假设现在本机环境是中文环境,使用的GBK编码,而当前的java程序使用的iso8859-1编码,则需要转码,需要String类的支持。
public byte[] getBytes(String charsetName)throws UnsupportedEncodingException
可以指定要使用编码
import java.io.OutputStream ;import java.io.FileOutputStream ;import java.io.File ;public class CharSetDemo02{ publicstatic void main(String args[]) throws Exception { Filef = new File("D:" + File.separator + "test.txt") ; // 实例化File类 OutputStreamout = new FileOutputStream(f) ; // 实例化输出流 byteb[] = "中国,你好!".getBytes("ISO8859-1") ; // 转码操作 out.write(b); // 保存 out.close(); // 关闭 }};
乱码产生的根本原因就是编码的不一致。
压缩流
在Java中为了减少传输时的数据量也专门提供了压缩流,可以将文件或者文件夹压缩成ZIP、JAR、GZIP等格式。
该流使用较少,因此只做简要介绍。
- java IO(三):数据操作流、合并流、回退流、对象序列化、字符编码问题、压缩流
- 12. JAVA IO Part 3 (数据操作流、合并流、压缩流、回退流、字符编码) ----- 学习笔记
- 黑马程序员--------java IO流 File类、Properties、打印流、合并流、对象序列化、随机读写、字符编码
- JAVA基础 day23 IO流的其他类 (对象的序列化 管道流 RandomAccessFile类(随机读取文件) DateStream(操作基本数据类型的流) 操作数组的流 )字符编码问题
- JAVA之旅(三十)——打印流PrintWriter,合并流,切割文件并且合并,对象的序列化Serializable,管道流,RandomAccessFile,IO其他类,字符编码
- java IO 字节流、字符流操作总结三之字符流、序列化和反序列化
- java-----IO流 操作字节数组的流对象,对象序列化,打印流,随机存储文件,合并流,管道流,操作基本数据类型的流对象
- 黑马程序员——>第二十一天<io流(对象序列化-管道流-字符编码)>
- 黑马程序员-IO流(对象序列化、RandomAccessFile 类、字符编码)
- IO流-对象序列化操作流
- java-IO流-字符编码
- IO流--文件切割合并&对象的序列化
- Java基础---IO(二)--Properties类、打印流、序列流、对象操作流、数据输入输出流
- JAVA基础学习(二十二)--IO流四-对象序列化、管道流、RandomAccessFile、DataStream、ByteArrayStream、转换流的字符编码
- Java IO流(对象序列化)
- 黑马程序员——Java基础——对象序列化、管道流、RandomAccessFile类、操作基本数据类型的流对象、字符编码
- Java IO流与对象IO序列化
- Java IO流与对象IO序列化
- hdu 1358 Period
- 那些职场失意人身上的特点
- remote object implements illegal remote interface
- MySQL: InnoDB 还是 MyISAM?
- 2014年4月操作系统份额:Windows XP仍然在26%以上,Linux微涨
- java IO(三):数据操作流、合并流、回退流、对象序列化、字符编码问题、压缩流
- PAT A 1005. Spell It Right (20)
- iOS7—Day by day—Day14:Interactive View Controller Transitions
- MakeSpace:什物云存储版Dropbox 融800万美元
- 索引的建立 更新策略
- C# TryParse 和 Parse
- Java 泛型通配符?解惑
- 一直对自定义监听器有疑问,所以转一下,有空理解下
- 【js设计模式笔记---接口】