您的位置:首页 > 职场人生

黑马程序员_JAVA_IO流2

2014-10-07 07:25 302 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

序列化

要序列化的对象需要实现Serializable接口,Serializable接口没有方法,为标记接口。UID为类定义一个标示,只能序列化堆里的数据static修饰的数据不能被序列化,transient修饰的数据不能被序列化,保证数据存在在堆内存而不存在在文本文件中,可以自定义。
public static final long serialVersionUID = 42L;
ObjectOutputStream
ObjectInputStream
序列化对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.txt"));
oss.writeObject(new Person("lili",23));
oss.close();
读取序列化对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.txt"));
Person p = (Person)ois.readObject();
ois.close();

管道流

PipeddInputStream和PipedOutputStream
输入输出可以直接进行连接,结合线程使用,不建议单线程,因为可能死锁
PipeddInputStream in = new PipeddInputStream();
PipedOutputStream out = new PipedOutputStream();
in.connect(out);//连接管道流

RandomAccessFile类

不属于IO体系的子类,直接继承object,但是是IO包中的成员,因为具备读写功能,该实例支持对随机文件的读取和写入。内部封装一个byte数组,通过指针对数组元素进行操作。可以通过getFilePointer获取指针的位置,通过seek改变指针的位置,内部封装了字节的输入流和输出流。

局限性:只能操作文件,而且操作文件有模式(r,rw),如果模式为只读r,不会创建文件,会读取已存在的文件,不存在,发生异常。模式为rw,要操作的文件不存在会自动创建,存在的话不覆盖。因为可以指定位置随机访问,所以可以实现多线程写入,多线程下载应用。

RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");//模式读写
raf.write("张三".getBytes());
raf.writeInt(97);写入四个字节
raf.wtite(97);写入一个字节

RandomAccessFile raf1 = new RandomAccessFile("fan.txt","r");//只读,屏蔽写的操作,new对象不覆盖

raf1.seek(8);//调整指针从角标为8的字节开始取
raf1.skipBytes(8);//跳过8个字节,不能往回跳

byte[] buf = new byte[4];
raf1.read(buf);
String name = new String(buf);
int age = raf1.readInt();//一次读四个字节,转换成int型

raf1.close();

DataInputStream和DataOutputStream

可以操作基本数据类型

DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));

dos.writeInt();
dos.writeBoolean();
dos.writeDouble();

dos.writeUTF("");//UTF-8修改版方法,只能用对应方法读取
八个字节两个字符,UTF-8六个字节两个字符
dos,close();

DataInputStream dis = new DataInputStream(new FileInputStream("dos.txt"));
dis.readInt();
dis.readBoolean();
dis.readDouble();

dis.readUTF();


ByteArrayInputStream和ByteArrayOutputStream

在构造时需要接收数据源,一个字节数组。构造时不用定义数据目的,因为内部封装一个可变数组。因为流对象是操作数组,不涉及底层资源调用,不需抛异常,不用关闭且关闭无效。可变长度缓冲区,随数据写入不断增长。

ByteArrayInputStream bis = new ByteArrayInputStream("adk".getBytes());
ByteArrayOutputStream bos = new ByteArrayOutputStream();

int by = 0;
while((by=bis.read())!=-1)
{
bos.write(by);
}

bos.writeTo(new FileOutputStream("a.txt"));//将流写入到文件中


用流的思想操作数组

操作字符的数组流

CharArrayReader和CharArrayWriter

字符编码

常见码表
ACSII 美国标准信息交换码
用一个字节的7位表示

ISO8859-1 拉丁码表,欧洲码表
用一个字节的8位表示

GB2312 中国的中文编码表
GBK 中国的中文编码表升级,融合更多的中文字符

Unicode 国际标准码,融合了多种文字
用两个字节表示一个文字
UTF-8 最多用三个字节表示一个字符

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("utf-8"),"UTF-8");//UTF-8编码
InputStreamReader osr = new InputStreamReader(new FileInputStream("utf-8"),"gbk");//gbk解码

编码:字符串变成字节数组

String--->byte[]; str.getBytes();

解码:字节数组变成字符串

byte[]--->new String("".getBytes());

默认编码是GBK

String s = "你好";
Byte[] b1 = s.getByte("GBK");编码
String s1 = new String(b1,"UTF-8");解码

遇到乱码通用解决办法:编码再解码。如果两种码表都识别中文会出现错误。

String s = "你好";
Byte[] b1 = s.getByte("GBK");编码
String s1 = new String(b1,"iso8859-1");解码
Byte[] b2 = s1.getByte("iso8859-1");
String s2 = new String(b2,"GBK");解码

"联通"两字符输入记事本保存再打开会出现乱码
因为中文默认用的JBK编码表
但是"联通"两个字符的字符头恰好符合UTF-8的码表,所以会使用UTF-8码表解码

UTF-8识别编码字节数的头位:

字节1
0

字节1
110
字节2
10

字节1
1110
字节2
10
字节3
10
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  IO流 序列化 管道流