-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
1、序列化对象
对象被序列化后,然后存到硬盘的文件中,然后读取的时候可以方便的读取,要被存到硬盘文件中的对象类,必须实现接
Serializable接口,此接口中没有抽象方法,是为了标识类的。
ObjectOutputStream的方法writeObject()和ObjectInputStream的方法readObject(),这两个方法是成对出现的,一个是写,一个是读。
注意:
1.当被序列化的对象存到了硬盘上后,如果原来的类更改了,那么再次读取的时候,会读取失败,因为他们的标识ID被更改了,所以要向更改后,仍可以读取的话,那么在序列化的时候,指定固定的标识ID。static final long serialVersionUID = 42L;
2.静态成员不能被序列化,因为序列化的都是在堆中,而静态的成员实在方法区中,如果非静态成员要向也不被序列化,那么由关键字:transient修饰,那么就会不被序列化。
3.当文件中存储了多个对象,那么读取的时候没调用一次readObject方法,就读取一个对象。
2、例子
用序列标识号来标识类,那么原来的类更改了一些操作,那么也可以继续使用硬盘中被序列化的文件对象。
import java.io.Serializable;
public class Person implements Serializable {
static final long serialVersionUID = 42L;
private String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return name + ":" + age;
}
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class SerDemo {
public static void main(String[] args) throws Exception {
// WritePerson();
ReadPerson();
}
/* 写 */
private static void ReadPerson() throws IOException,FileNotFoundException,
ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
"F:\\per.txt"));
Person p = (Person) ois.readObject();
System.out.println(p);
}
/* 读 */
private static void WritePerson() throws IOException,FileNotFoundException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
"F:\\per.txt"));
oos.writeObject(new Person("zhangsan", 23));
oos.close();
}
}
结果:
zhangsan:23
3、管道流
将输入流和输出流。连接起来有两种方式:利用构造函数,或者用connect()方法。
public class Write implements Runnable {
private PipedOutputStream out = null;
public Write(PipedOutputStream out) {
super();
this.out = out;
}
public void run() {
try {
System.out.println("开始写入数据,等待");
Thread.sleep(4000);
out.write("guandao".getBytes());
out.close();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
import java.io.IOException;
import java.io.PipedInputStream;
public class Read implements Runnable {
private PipedInputStream in = null;
public Read(PipedInputStream in) {
this.in = in;
}
public void run() {
try {
System.out.println("没有数据可读");
byte [] b=new byte[1024];
int len=in.read(b);
System.out.println("读到数据");
System.out.println(new String(b,0,len));
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class PideDemo {
public static void main(String[] args)throws IOException {
PipedOutputStream pds=new PipedOutputStream();
PipedInputStream pis=new PipedInputStream();
pds.connect(pis);//链接
Write w=new Write(pds);
Read r=new Read(pis);
new Thread(w).start();
new Thread(r).start();
}
}
结果:
开始写入数据,等待
没有数据可读
读到数据
Guandao
4、RandomAccessFile
随机访问文件,自身具备读写方法
1.特点:
不是IO包中的子类,直接继承Object但是是IO包成员,既可以读也可以写。内部封装一个数组,通过指针进行操作。
可以通过getFilePointer()和seek()方法设置指针的位置
2. 读写原理:就是内部分装了字节输入流和输出流。
3.通过构造函数知,只能操作文件。有模式:r,rw,rws,rwdbv
4. 跳过指定的字节数skipBytes(n);只能向后跳
5.如果模式是r,不会创建文件,会去读一个已经存在的文件,不存在,则抛出异常。如果模式是rw,操作文件不存在,则自动创建,要是文件存在,则不会覆盖。
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
public class RandomAccessFileDemo {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile(new File("F:\\demo.txt"),
"rw");// 可读可写
/*写*/
raf.write("张三".getBytes());
raf.write(23);
raf.close();
raf = new RandomAccessFile(new File("F:\\demo.txt"), "rw");// 可读可写
/*读*/
byte[] b = new byte[4];
int l = raf.read(b);
System.out.println(new String(b, 0, l));
}
}
5、 DataInputStream和DataOutputStream
用来操作基本数据类型的类。
注意:writeUTF方法是用来操作指定写入的编码是utf-8方式,但是他是修改版本,在此写入的文件,只能应此对象来读取,其他的对象是读取不出来的,因为是修改版的。
public static void main(String[] args) throws IOException {
DataWrite();
DataRead();
}
public static void DataWrite() throws IOException{
DataOutputStream out=new DataOutputStream(new FileOutputStream("F:\\data.txt"));
out.writeInt(123);
out.writeBoolean(true);
out.writeDouble(34.87);
out.writeDouble(1.1);
out.close();
}
public static void DataRead() throws IOException{
DataInputStream in=new DataInputStream(new FileInputStream("F:\\data.txt"));
int a=in.readInt();
boolean b=in.readBoolean() ;
double c=in.readDouble();
in.close();
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
结果:
123
true
34.87
6、ByteArrayInputStream和ByteArrayOutputStream
用于操作字节数组
这两个流对象操作的数组,没有使用系统资源(没有创建文件),所以不用关闭。
ByteArrayInputStream:不用定义数据目的,因为封装了一个可变的字节数组
在流操作的规律中:
源和目的除了:键盘和文件,还有内存,内存就是ByteArrayInputStream和ByteArrayOutputStream,就是操作字节数组流。
public static void main(String[] args) throws IOException {
ByteArrayInputStream in=new ByteArrayInputStream("abcd".getBytes());
ByteArrayOutputStream out=new ByteArrayOutputStream();
int ch=0;
while((ch=in.read())!=-1){
out.write(ch);
}
System.out.println(out.size());
System.out.println(out.toString());
}
7、编码表
ISO8859-1:属于单字节编码方式,主要是在0~255字符范围,只要在英语在英文上。
GBK/GBK2312:中文的编码方式,只要是标识汉字,
Unicod:使用的是16进制的编码方式。
UTF:可以是字符的长度是1-6字符,这样可以节约空间。兼容所有字符。
转换流之间的编码
编码表:就是把各个国家的文字全部用数字表示出来,应用于计算机,那么这样就形成了一个表,就是编码表
GBK:一个汉字站两个字节
UTF-8:一个汉字占三个字节
同样的编码方式要用同样的变法方式读取,否则会出现乱码
public class Text {
public static void main(String[] args) throws IOException {
//writeTxt();
readTxt();
}
public static void writeTxt() throws IOException{
OutputStreamWriter writer=new OutputStreamWriter(new FileOutputStream("F:\\utf.txt"),"utf-8");
writer.write("大家好");
writer.close();
}
public static void readTxt() throws IOException{
InputStreamReader reader=new InputStreamReader(new FileInputStream("F:\\utf.txt"),"utf-8");
char []bu=new char[20];
int len=reader.read(bu);
System.out.println(new String(bu,0,len));
reader.close();
}
}
8、字符的编码和解码
编码:字符串变成字节数组String—>byte[]String.getBytes(charsetName);
解码:字节数组变成字符串byte[]->String new String(byte[],chatsename)
public class Text {
public static void main(String[] args) throwsUnsupportedEncodingException {
String s1="你好";
byte [] b1=s1.getBytes("GBK");
System.out.println(Arrays.toString(b1));//编码表
//假如编码方式变了
String s2=new String(b1,"ISO8859-1");
System.out.println(s2);
byte [] b2=s2.getBytes("ISO8859-1");
System.out.println(Arrays.toString(b2));//编码表
System.out.println(new String(b1,"GBK"));
}
}
结果:
[-60, -29, -70, -61]
????
[-60, -29, -70, -61]
你好