I/O流——其他流
其他流
一、ObjectInputStream/ObjectOutputStream
① ObjectInputStream和ObjectOutputStream分别与FileInputStream和FileOutputStream一起使用时,可以对应用程序提供对对象的持久存储。我们把对象以某种特定的编码格式写入称之为“序列化”。把写入的编码格式内容还原成对象称之为“反序列化”。
② 被序列化的对象必须实现Serializable接口。
序列化示例:
//必须实现Serializable接口
class Student implements Serializable{
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
} }
主方法:
Student stu=new Student("zhangsan", 30);
FileOutputStream fos=new FileOutputStream("d:/test.txt");
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeObject(stu);//把对象序列化到指定的文件输出流中
oos.close();//释放资源
反序列化:
主方法:
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("d:/test.txt"));
try {
Student stu2= (Student)ois.readObject();
System.out.println(stu2);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
ois.close();
反序列化成功之后,再在Student中添加一个地址属性。
private String address;
发现不能反序列化了,因为序列化的对象与反序列化的对象不一致。
解决办法:Eclipse的Student类行号左边有一个小灯,
添加一个版本号。再次进行序列化操作,新增属性后反序列化也能成功,它会自动取出序列化中不存在的属性。
二、InputStreamReader/OutputStreamWriter
①转换流是指将字节流与字符流之间的转换。
②转换流的出现方便了对文本的读写,她在字符流与字节流之间架起了一座桥梁,使原本毫无关联的两种流操作能进行转化,提高了程序的灵活性。
③ 节流中的数据都是字符时,转成字符流操作更高效。
④ 如果使用非默认编码保存文件或读取文件时,需要用到转换流。因为字节流的重载构造方法中有指定编码格式的参数,而FileReader与FileWriter是默认编码的文本文件。
⑤ 常见的编码表
a) ASCII:美国标准信息交换码。用一个字节的7位可以表示。
b) ISO8859-1:拉丁码表。欧洲码。表用一个字节的8位表示。
c) GB2312:中国的中文编码表。
d) GBK:中国的中文编码表升级,融合了更多的中文文字符号。
e) Unicode:国际标准码,融合了多种文字。所有文字都用两个字节来表示,Java语言使用的就是Unicode。
f) UTF-8:最多用三个字节来表示一个字符。
g) ……
将内容以指定编码的格式存入文件:
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("d:/code.txt"), "utf-8");
BufferedWriter bw=new BufferedWriter(osw);
bw.write("你好");
bw.close();
读取文件:
BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("d:/code.txt"), "utf-8"));
String line=null;
while((line=br.readLine())!=null){
System.out.println(line);
}
br.close();
三、RandomAccessFile 随机访问文件
①支持对随机访问文件的读取和写入。
②随机访问文件的行为类似存储在文件系统中的一个大型byte数组。存在指向该隐含数组的光标或索引,称为文件指针。
③ 入操作从文件指针开始读取字节,随着对字节的读取而前移此文件指针。
④ 如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,随着对字节的写入而前移此文件指针。
⑤ 写入隐含数组末尾之后的输入操作导致该数组扩展。
⑥ 该文件指针可用通过getFilePointer方法读取,通过seek方法设置。
案例说明:创建一个Person类,内有name属性占15个字符,即30个字节,age属性4个字节,共34个字节。将多个Person对象放入RandomAccessFile中。然后在指定的位置上取出Person对象(名字,年龄)。
创建一个Person类
class Person {
private String name;
private int age; public Person() { } public Person(String name, int age) {
StringBuilder builder = null;
if (name != null) {
builder = new StringBuilder(name);
} else {
builder = new StringBuilder(15);
}
builder.setLength(15);// 固定长度为15个字符,不满15时,'\u0000'
this.name = builder.toString();
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
StringBuilder builder = null;
if (name != null) {
builder = new StringBuilder(name);
} else {
builder = new StringBuilder(15);
}
builder.setLength(15);// 固定长度为15个字符,不满15时,'\u0000'
this.name = builder.toString();
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} // 每个对象所占的字节数
public static int size() {
return 34;
} }
读取名字时不用将全部字节都读取出来,所以应该替换空字节。方法如下,将其写在与主方法同一个类下即可
private static String readName(RandomAccessFile randomaccessFile)
throws IOException {
char[] name = new char[15];
for (int i = 0; i < name.length; i++) {
name[i] = randomaccessFile.readChar();
}
return new String(name).replace('\u0000', ' ');
}
主方法:
Person[] persons = { new Person("zhangsan", 10),
new Person("lisi", 24), new Person("wangwu", 36),
new Person("zhaoliu", 66) };
RandomAccessFile randomaccessFile = new RandomAccessFile(
"d:/test2.txt", "rw");
// 写入数据到RandomAccessFile这个对象中、
for (int i = 0; i < persons.length; i++) {
randomaccessFile.writeChars(persons[i].getName());
randomaccessFile.writeInt(persons[i].getAge());
}
// 读取指定位置上的Person对象
Scanner scanner = new Scanner(System.in);
System.out.println("读取第几个Person对象数据");
int num = scanner.nextInt();
// 使用seek方法来操作存取位置
randomaccessFile.seek((num - 1) * Person.size());
Person person = new Person();
person.setName(readName(randomaccessFile));
person.setAge(randomaccessFile.readInt());
System.out.println("姓名:" + person.getName());
System.out.println("年龄:" + person.getAge());
randomaccessFile.close();
运行后在Console窗口上输入要获取的位置即可,超出位置会抛异常。
I/O流——其他流的更多相关文章
- [源码]ObjectIOStream 对象流 ByteArrayIOStream 数组流 内存流 ZipOutputStream 压缩流
1.对象流 import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File ...
- IO流03_流的分类和概述
[概述] Java的IO流是实现输入/输出的基础,它可以方便的实现数据的输入/输出操作. Java中把不同的输入/输出源(键盘.文件.网络连接)抽象表述为"流"(Stream). ...
- Java基础知识强化之IO流笔记41:字符流缓冲流之复制文本文件案例02(使用 [ newLine() / readLine() ] )(重要)
1. 使用字符流缓冲流的特殊功能 [ newLine() / readLine() ] 需求:把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中 数据源: a.txt -- 读取数据 ...
- Java基础知识强化之IO流笔记39:字符流缓冲流之复制文本文件案例01
1. 字符流缓冲流之复制文本文件案例 需求:把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中 数据源: a.txt -- 读取数据 -- 字符转换流 -- InputStreamRe ...
- Java基础知识强化之IO流笔记38:字符流缓冲流之BufferedWriter / BufferedReader使用
1. 字符流缓冲流: 字符流为了高效读写,也提供了对应的字符缓冲流. BufferedWriter:字符缓冲输出流 BufferedReader:字符缓冲输入流 2. BufferedWriter使用 ...
- JAVA之旅(二十七)——字节流的缓冲区,拷贝mp3,自定义字节流缓冲区,读取键盘录入,转换流InputStreamReader,写入转换流,流操作的规律
JAVA之旅(二十七)--字节流的缓冲区,拷贝mp3,自定义字节流缓冲区,读取键盘录入,转换流InputStreamReader,写入转换流,流操作的规律 我们继续来聊聊I/O 一.字节流的缓冲区 这 ...
- 【Java基础】【21IO(字符流)&字符流其他内容&递归】
21.01_IO流(字符流FileReader) 1.字符流是什么 字符流是可以直接读写字符的IO流 字符流读取字符, 就要先读取到字节数据, 然后转为字符. 如果要写出字符, 需要把字符转为字节再写 ...
- -1-4 java io java流 常用流 分类 File类 文件 字节流 字符流 缓冲流 内存操作流 合并序列流
File类 •文件和目录路径名的抽象表示形式 构造方法 •public File(String pathname) •public File(String parent,Stringchild) ...
- Java转换流、缓冲流、流操作规律整理
转换流 1.1 OutputStreamWriter类 OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的字符编码表,将要写入流中的字符编码成字 ...
- java-IO流-其他流
###22.01_IO流(序列流)(了解) * 1.什么是序列流 * 序列流可以把多个字节输入流整合成一个, 从序列流中读取数据时, 将从被整合的第一个流开始读, 读完一个之后继续读第二个, ...
随机推荐
- 【原创】ORACLE常见使用问题解决
ORACLE常见使用问题解决 一.安装了oracle客户端后,发现plsql客户端找不到之前已经配置过的TNS连接信息 或许大家再使用ORACLE软件的过程中,经常会遇到这样的问题: 问题现象描述: ...
- nodejs express环境配置
下载安装最新版nodejs,安装完毕运行命令 node -v 查看版本以及是否安装成功. 然后安装express插件,命令 npm install -g express (全局) , express ...
- JavaScript能干什么?
真的是长见识了,JavaScript居然能做除了WEB界面外运行于任何平台的APP,而且可以做服务器端,还有天理和王法吗?JavaScript到底有多神奇,要不要重新上路,老程序员何去何从,自然要先网 ...
- Extjs 百度地图扩展
var bmapps; Bsprint.EditMapInfoWindow = Ext.extend(Ext.Window, { form: null, constructor: function ( ...
- pycharm激活码,拿走不谢
激活码 新下载pycharm编辑器以后,会遇到一个激活的问题,否则只能试用30天 43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QTczWVlKIiwibGljZW5zZWVO ...
- 《疯狂Java讲义》(三) ---- JDK&JRE&JVM&CLASSPATH
JDK: Java SE Development Kit, Java标准版开发包.包括Java编译器,JRE,以及常用的Java类库等. JRE: Java Runtime Environment,运 ...
- git 使用入门
参考教程: 廖雪峰的官方网站 MY UBUNTU 安装: sudo apt-get install git GIT 理解: 选定的目录为git的工作区.该目录下的任何改动,git都会记录为工作区的修改 ...
- 习课省市区的三级联动(cxselect的使用)
1,api:http://www.jq22.com/jquery-info32382,demo:http://blog.csdn.net/luo201227/article/details/38844 ...
- 正则表达式test验证的“bug”
在使用正则表达式对某些字符串进行验证时,我们常常会使用到test方法,而该方法也隐藏着一个陷阱,今天就让我们来看一下这个问题. var str = 'hello jack, hello rose'; ...
- 中文字号VS英文字号(磅)VS像素值
中文字号VS英文字号(磅)VS像素值八号=5磅(5pt) ==(5/72)*96=6.67 =6px 七号=5.5磅 ==(5.5/72)*96=7.3 =7px 小六=6.5磅 ==(6.5/72) ...