---------------------- android培训、java培训、期待与您交流! ----------------------
ObjectOutputStream也是字节输出流的子类:
java.lang.Object java.io.OutputStream java.io.ObjectOutputStream
ObjectInputStream是字节输入流的子类:
java.lang.Object java.io.InputStream java.io.ObjectInputStream
ObjectOutputStream通过writeObject(Object obj) ObjectInputStream通过readObject() 通过一个简单的程序测试:
publicstaticvoid objetcSeri()throws Exception {
}
控制台 出现如下错误:
说明Person这个类没有实现Serializable接口
更正错误后发现硬盘中多了一个person.obejct文件
其内容为一些我们看不懂的字符:
那么我们是否通过ObjectInputStream读取到文件的内容呢?
public static void readObject() throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.object"));
Person person = (Person)ois.readObject();
System.out.println(person);
}
控制台输出结果:name:johnny age:21 country:CHINA
我们来看一下Serializable接口的API
这意思是说:如果实现了序列化接口的类没有显示声明serialVersionUID变量,序列化运行时将计算一个默认的serialVersionUID的值为这个类基于类的变量方面的值
.我们强烈建议所有实现序列化接口的类都要显示的声明serialVersionUID变量,因为默认的serialVersionUID变量值对于类的修改是非常敏感的,因为他的值就是根据
类成员的签名而生成的而不是系统随机生成的,假设我们对类A进行序列化,在一般情况下我们可以反序列化得到类A的信息,如果我们一旦修改了类A,
那么我们再次反序列化就会出现java.io.InvalidClassException 异常的,因为第一次编译类A的时候他的id是一个值,
你修改类A后在再次编译id的值已经变了.因此为了保证在不同的编译器serialVersionUID变量的值一致性,
所以建议把该变量定义成一个private的常量.
下面来模拟这种情况:现在我修改Person类:如下
重新反序列化一次:
控制台打印店异常:Exception in thread "main" java.io.InvalidClassException: com.huaxia.day21.Person; local class incompatible:
stream classdesc serialVersionUID = -379036032685453711,
local class serialVersionUID = 1208026685571330753
---------------------------------------- 管道流:-------------------------------------------
在Java中,可以使用管道流进行线程之间的通信,输入流和输出流必须相连接,这样的通信有别于一般的Shared Data通信,其不需要一个共享的数据空间。
java.lang.Object java.io.OutputStream java.io.PipedOutputStream
package com.huaxia.day21;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
class Read implements Runnable {
private PipedInputStream is;
public Read(PipedInputStream is) {
this.is = is;
}
public void run() {
int len=0;
byte[] buffer = new byte[1024];
try {
//如果不使用循环,如果写入的数据超过1024,那么读的就不完整了
while((len=is.read(buffer))!=-1){
System.out.println(new String(buffer,0,len));
}
is.close();
} catch (IOException e) {
throw new RuntimeException("管道流读取失败");
}finally{
if(is!=null)
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class Write implements Runnable {
private PipedOutputStream os;
public Write(PipedOutputStream os) {
this.os = os;
}
public void run() {
try {
//向管道输出流写入数据
os.write("hello world!".getBytes());
} catch (IOException e) {
e.printStackTrace();
}finally{
if(os!=null)
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class PipedStreamTest {
public static void main(String[] args) throws IOException {
PipedInputStream pis= new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream();
//连接管道流,使之能够通信
pis.connect(pos);
//启动写入线程
new Thread(new Write(pos)).start();
//启动读取线程
new Thread(new Read(pis)).start();
}
}
java.lang.Object
java.io.RandomAccessFile
public static void readFile() throws IOException{
RandomAccessFile raf = new RandomAccessFile("random.txt","r");
System.out.println(raf.readInt());
}
int
to the file as four bytes, high byte first.
public static void writeFile() throws IOException{
RandomAccessFile raf = new RandomAccessFile("random.txt","rw");
//下面写入两个人名和其年龄
raf.write("张三".getBytes());
raf.writeInt(23);
raf.write("李四".getBytes());
raf.writeInt(35);
raf.close();
}
public static void readFile() throws IOException{
RandomAccessFile raf = new RandomAccessFile("random.txt","r");
byte[] buffer = new byte[4];
raf.read(buffer);//读取4个字节
int age = raf.readInt();//再读取4个字节
System.out.println("name="+new String(buffer)+"\tage="+age);
}
public static void readFile_2() throws IOException{
RandomAccessFile raf = new RandomAccessFile("random.txt","r");
raf.seek(8*1);
byte[] buffer = new byte[4];
raf.read(buffer);//读取4个字节
int age = raf.readInt();//再读取4个字节
System.out.println("name="+new String(buffer)+"\tage="+age);
}
public static void writeFile_2() throws IOException{
RandomAccessFile raf = new RandomAccessFile("random.txt","rw");
raf.seek(8*3);
//下面写入两个人名和其年龄
raf.write("王五".getBytes());
raf.writeInt(99);
raf.close();
}
java.lang.Object java.io.InputStream java.io.FilterInputStream java.io.DataInputStream 和
java.lang.Object java.io.OutputStream java.io.FilterOutputStream java.io.DataOutputStream
public static void writeData() throws IOException {
DataOutputStream dos = new DataOutputStream(new FileOutputStream(
"dataType.txt"));
dos.writeInt(109);
dos.writeDouble(123.089);
dos.writeBoolean(true);
dos.close();
}
public static void readData() throws IOException {
DataInputStream dis = new DataInputStream(new FileInputStream(
"dataType.txt"));
int num = dis.readInt();
double d = dis.readDouble();
boolean b = dis.readBoolean();
System.out.println("int:"+num+"\tdouble:"+d+"\tboolean:"+b);
}
输出结果:int:109 double:123.089 boolean:true
public static void writeData_2() throws IOException {
DataOutputStream dos = new DataOutputStream(new FileOutputStream(
"utfdata.txt"));
dos.writeUTF("你好中国");
dos.close();
}
现在我们使用换行流往文件中写入相同的数据:
public static void writeData_3() throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("uft-8data.txt"),"utf-8");
osw.write("你好中国");
osw.close();
}
public static void readData_2() throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("utfdata.txt"),"utf-8");
BufferedReader bw =new BufferedReader(isr);
//因为是测试,数据只有一行 就不循环
System.out.println(bw.readLine());
}
public static void readData_3() throws IOException {
DataInputStream dis = new DataInputStream(new FileInputStream("utfdata.txt"));
System.out.println(dis.readUTF());
}
java.lang.Object java.io.InputStream java.io.ByteArrayInputStream
ByteArrayInputStream(byte[] buf) ByteArrayInputStream(byte[] buf, int offset, int length)
java.lang.Object java.io.OutputStream java.io.ByteArrayOutputStream ByteArrayOutputStream() ByteArrayOutputStream(int size)
我们知道在字节流中本来就封装了字节数组,那为什么还要出现这操作字节数组的流呢?
public static void main(String[] args) throws UnsupportedEncodingException {
String value = "你好中国";
byte[] b = value.getBytes();// 默认按gbk编码
System.out.println(Arrays.toString(b));
System.out.println(new String(b));
}
输出结果:
public static void main(String[] args) throws UnsupportedEncodingException {
String value = "你好中国";
byte[] b = value.getBytes();// 默认按gbk编码
System.out.println(Arrays.toString(b));
String decode = new String(b, "iso8859-1");// 默认按gbk解码
System.out.println(decode);
byte[] b2 = decode.getBytes("iso8859-1");
System.out.println(Arrays.toString(b2));
System.out.println(new String(b,"gbk"));
}
这个程序就可以解决这个问题,输出结果为:
public static void main(String[] args) {
String value = "联通";
byte[] b = value.getBytes();
for(byte by : b){
//打印它的二进制形式
System.out.println(Integer.toBinaryString(by&255));
}
}
我们知道GBK每两个字节表示一个字符,而UTF-8不是,那么在底层字节流在读取的时候,她怎么知道几个字节表示一个字符呢?
---------------------- android培训、java培训、期待与您交流! ----------------------