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

黑马程序员:IO 学习<二>

2013-03-27 13:18 501 查看
------- android培训java培训、期待与您交流!
----------

(1)--------------------------------对象流,序列化流(理解)

ObjectOutputStream:

void writeObject(Object obj)

ObjectInputStream:

Object readObject()

注意:

A:如果一个类的对象要想被对象流操作,就必须实现序列化接口。

B:这个接口只是起到标识的作用,没有方法需要实现。

C:如果类的简单改动不像影响程序的运行,我们就自己给定序列化id号。

D:序列化:把对象按照流一样的方式在网络中传输和写入文本文件。

反序列化:把文本文件的数据或者网络中传递的流对象数据解析成一个对象。

前面呢,我们已经可以往文件里面写入文本,简单数据。

* 现在呢,我要把一个对象写入到文本文件。该怎么做呢?

* 我们应该定义一个自定类。

* 通过查看API,我们看到了对象的读写:

* ObjectOutputStream:

* void writeObject(Object obj)

* ObjectInputStream:

* Object readObject()

*

* 对象流,序列化流。

*/

public class ObjectStreamDemo {

public static void main(String[] args) throws Exception {

// write();

read();

}

private static void read() throws Exception {

// 反序列化

ObjectInputStream ois = new ObjectInputStream(new FileInputStream(

"oos.txt"));

// 读取数据

Object obj = ois.readObject();

// 释放资源

ois.close();

Person p2 = (Person) obj;

System.out.println(p2.getName() + "***" + p2.getAge());

}

private static void write() throws Exception {

// 我要把Person写到文件

// 创建对象输出流对象

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(

"oos.txt"));

// 写数据

Person p = new Person("林青霞", 25);

oos.writeObject(p);

// 释放资源

oos.close();

}

}

NotSerializableException:

当对象要被序列化流对象操作的时候,必须实现一个接口。

* 通过查看Serializable我们知道类可以通过实现 java.io.Serializable 接口以启用其序列化功能。

* Exception in thread "main" java.io.InvalidClassException:

* cn.itcast_01.Person; local class incompatible: stream classdesc serialVersionUID = 2586984019240964030,

* local class serialVersionUID = -241056507998041204

*

* Serializable是对类打了标记,这个时候,

在生成的class文件中会有一个标记号自动生成。serialVersionUID = 2586984019240964030

* 那么,这样的话,我们把这个对象写入到文件中的时候,

也会把这个标记号写到文件中。serialVersionUID = 2586984019240964030

* 但是,我们刚才的动作,是把写给关闭了,

那么,这个时候,文件中的标记号应该还是:serialVersionUID = 2586984019240964030

* 这个时候,我们又重写在Person类里面修改了一个成员变量的修饰符,一旦修改,这个标记号就会改动。也就是现在的:serialVersionUID = -241056507998041204

* 我们再次读取数据的时候,class中的标记号和文件中的标记号不一致了,就导致了现在的问题。

* class文件和对象写入的文件应该保证一致。

* 我们现在应该去想一个办法,在类中把标记号给固定死,那么,生成的class中的标记号也就是固定的了。

* 问题来了,这个标记号该怎么定义才能让jvm识别。

* 这个就是用来被jvm识别的:private static final long serialVersionUID = -241056507998041204L;

*

*/

public class Person implements Serializable {

*

* 按照序列化的方式写多个对象到文件。

*

* Exception in thread "main" java.io.EOFException:当输入过程中意外到达文件或流的末尾时,抛出此异常。

* 流以-1作为结束条件,而你现在要得到的是一个对象,所以不成功。

*

* 存储多个对象的时候,建议把多个对象添加到一个集合中,把结合对象作为一个对象写入。

* 读取的时候,就读取一次即可。

*

* 总结代码。分类整理。

*/

public class ObjectStreamTest {

public static void main(String[] args) throws Exception {

write();

read();

}

private static void read() throws Exception {

// 反序列化

ObjectInputStream ois = new ObjectInputStream(new FileInputStream(

"oos.txt"));

// 读取数据

// Object obj = ois.readObject();

// Object obj2 = ois.readObject();

// Object obj3 = ois.readObject();

// try {

// Object obj = null;

// while ((obj = ois.readObject()) != null) {

// Person p = (Person) obj;

// System.out.println(p.getName() + "***" + p.getAge());

// }

// } catch (EOFException e) {

// // 但是这样解决不好,这还不如不解决

// // 处理的时候,一定要给出提示,不要认为的把异常给隐藏掉

// }

Object obj = ois.readObject();

ArrayList<Person> array = (ArrayList<Person>) obj;

for (Person p : array) {

System.out.println(p.getName() + "***" + p.getAge());

}

// 释放资源

ois.close();

// Person p = (Person) obj;

// System.out.println(p.getName() + "***" + p.getAge());

// Person p2 = (Person) obj2;

// System.out.println(p2.getName() + "***" + p2.getAge());

// Person p3 = (Person) obj3;

// System.out.println(p3.getName() + "***" + p3.getAge());

}

private static void write() throws Exception {

// 我要把Person写到文件

// 创建对象输出流对象

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(

"oos.txt"));

// 写数据

Person p = new Person("林青霞", 25);

// oos.writeObject(p);

Person p2 = new Person("林志玲", 22);

// oos.writeObject(p2);

Person p3 = new Person("刘德华", 40);

// oos.writeObject(p3);

ArrayList<Person> array = new ArrayList<Person>();

array.add(p);

array.add(p2);

array.add(p3);

oos.writeObject(array);

// 释放资源

oos.close();

}

}

打印流:

* PrintWriter://字符打印流

* PrintStream://字节打印流

*

* 为什么要学习Print呢?

* 特点:

* 1:可以把任意类型的数据写入文件

* 2:它是可以直接操作设备(文件)的流对象流对象很多,那么,哪些流对象时可以直接操作文件的呢?

* 观察构造方法,如果可以传递File file参数和String fileName参数同时存在,

说明该流对象就是可以操作文件的对象。

* 3:能够自动刷新。前提是:要启动自动刷新,使用println、printf 或 format的时候才可以。

* 不但能够刷新,还能够自动换行。

*/

public class PrintWriterDemo {

public static void main(String[] args) throws IOException {

// write1();

// write2();'

write3();

}

// 使用println方法自动刷新

private static void write3() throws IOException {

// 创建打印流对象,启用自动刷新

PrintWriter pw = new PrintWriter(new FileWriter("pw.txt"),true);

// 写入数据

pw.println("haha");

pw.println("hehe");

pw.println("xixi");

pw.println("heihei");

pw.println("gaga");

//释放资源

pw.close();

}

// 使用print方法写入不同数据类型的数据

private static void write2() throws IOException {

// 创建对象

PrintWriter pw = new PrintWriter("b.txt");

// 写入数据

pw.print(true);

pw.print(123);

pw.print("hell");

pw.flush();

pw.close();

}

// PrintWriter作为基本的Writer体系的使用

private static void write1() throws IOException {

// 创建打印流对象

PrintWriter pw = new PrintWriter("a.txt");

// 下面这个不可以

// BufferedWriter bw = new BufferedWriter("a.txt");

// 调用pw的write方法

pw.write("hello");

pw.flush();

// 释放资源

pw.close();

}

}

Properties:是Hashtaable的子类,具有Map集合的特点。它还可以和io进行结合使用。它的键和值都是字符串。

Properties作为Map体系使用。

把Properties集合中的数据写入到文本文件中。

思路:

1:得到有数据的集合对象。

2:遍历集合,获取键和值

3:把键和值存入文件

那么, 什么又是我们说的结合呢?

也就是说,我们不需要看到基本的读写操作。

特殊方法:

1:根据键获取值

* String getProperty(String key):根据键获取值

* String getProperty(String key, String defaultValue):当键对应的值存在,就返回值,否则,就返回给定的默认值。

* Object setProperty(String key, String value):当键存在的时候,就是修改动作,当键不存在的时候,就是添加动作。

*

* 2:load:把键值对的文本数据加载到集合中

* load(InputStream is)

* load(Reader r)

2:list 把集合中的数据写入文本文件

list(PrintStream out)

list(PrintWriter out)

3:load:把键值对的文本数据加载到集合中

* load(InputStream is)

* load(Reader r)

4: store:保存数据(重新保存到Properties里面的文件里面)

store(OutputStream os,String str)

store(Writer w,String str)

JDK的bin目录下有一个工具:

1、native2ascii a.txt b.txt

2、native2ascii b.txt -reverse c.txt

例:------

public class PropertiesDemo {

public static void main(String[] args) {

// 创建集合对象

Properties prop = new Properties();

System.out.println("prop:" + prop);

prop.put("hello", "haha");

prop.put("world", "hehe");

System.out.println("prop:" + prop);

// 遍历方式

Set<Object> set = prop.keySet();

Iterator<Object> it = set.iterator();

while (it.hasNext()) {

Object key = it.next();

Object value = prop.get(key);

System.out.println(key + "***" + value);

}

}

}

例:

*

* 请问应用在哪里?

* 玩过游戏吗?加载游戏进度。

*/

public class PropertiesDemo3 {

public static void main(String[] args) throws IOException {

// 创建集合对象

Properties prop = new Properties();

System.out.println("prop:" + prop);

// load(Reader r)

FileReader fr = new FileReader("prop.txt");

prop.load(fr);

fr.close();

System.out.println("prop:" + prop);

}

}

/*

* 游戏进度的保存。

*/

public class PropertiesDemo4 {

public static void main(String[] args) throws IOException {

Properties prop = new Properties();

// 把文本文件中的键值对数据加载到集合中

FileReader fr = new FileReader("prop.txt");

prop.load(fr);

fr.close();

// System.out.println("prop:" + prop);

prop.setProperty("lisi", "50");

// System.out.println("prop:" + prop);

// 保存数据

// store(Writer w,String str);

FileWriter fw = new FileWriter("prop.txt");

prop.store(fw, "name and age"); // 第二个参数其实就是解释说明数据的意义

fw.close();

}

}

JDK的bin目录下有一个工具:

native2ascii a.txt b.txt

native2ascii b.txt -reverse c.txt

查找文件prop.txt中,看有没有键为lisi的值,如果有,则把其值修改为35

*

* 思路:

1:把prop.txt中的键值对数据加载到Properties集合中。load

2:遍历这个集合,获取到每一个键,进行判断。

如果有键为lisi的,则把其值修改为35

3:最后,把改变后的集合数据保存到prop.txt文件中。store

*/

public class PropertiesTest {

public static void main(String[] args) throws IOException {

// 把prop.txt中的键值对数据加载到Properties集合中。

Properties prop = new Properties();

FileReader fr = new FileReader("prop.txt");

prop.load(fr);

fr.close();

// System.out.println("prop:" + prop);

// 遍历这个集合,获取到每一个键,进行判断。

Set<Object> set = prop.keySet();

for (Object key : set) {

if ("lisi".equals(key)) {

prop.setProperty(String.valueOf(key), String.valueOf(35));

break;

}

}

// 最后,把改变后的集合数据保存到prop.txt文件中

FileWriter fw = new FileWriter("prop.txt");

prop.store(fw, "这是数据表示姓名和年龄");

fw.close();

}

}

编码表:就是由数字及其表示的字符组成的一张数据表:

ASCII

ISO-8859-1码表

GBK

GBK2312

BIG5

UTF-8

UTF-16

为了实现国际化,国际化标准组织,就做了统一规定,用统一的编码表。

unicode编码。

字符串编码问题:

*

* 编码:

* 把能够看懂的变成看不懂的。

* String -- getBytes()

* 解码:

* 把看不懂的变成能够看懂的。

* byte[] -- String

*/

----------------------------------------------------------

public class StringEncode {

public static void main(String[] args) throws UnsupportedEncodingException {

// 创建一个字符串

String str = "你好";

// 编码

// byte[] bys = str.getBytes();

// -60, -29, -70, -61

// byte[] bys = str.getBytes("GBK");

// -28, -67, -96, -27, -91, -67

byte[] bys = str.getBytes("UTF-8");

System.out.println("bys:" + Arrays.toString(bys));

// 解码

// String s = new String(bys);

// 浣犲ソ

String s = new String(bys, "GBK");

// ???

// String s = new String(bys, "UTF-8");

System.out.println("s:" + s);

}

}

------------------------------------------

* 在IO流操作中的编码问题:

* 如果你想在io流操作中指定编码,得使用转换流。

* 只有转换流才可以指定编码。

* 字符流 = 字节流 + 编码表

*/

public class EncodeDemo {

public static void main(String[] args) throws IOException {

// 这里使用了默认编码表GBK

// OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(

// "osw.txt"));

// OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(

// "osw.txt"), "GBK");

// FileWriter osw = new FileWriter("osw.txt");

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(

"osw.txt"), "UTF-8");

osw.write("中国");

osw.close();

// InputStreamReader isr = new InputStreamReader(new FileInputStream(

// "osw.txt"), "UTF-8");

InputStreamReader isr = new InputStreamReader(new FileInputStream(

"osw.txt"), "GBK");

char[] chs = new char[1024];

int len = isr.read(chs);

System.out.println(String.copyValueOf(chs, 0, len));

isr.close();

}

}

如果保证数据不出现乱码的现象。就把编码改成相同的样式

如何使用面向对象的思想思考问题

1、分析该系统有哪些类

2、每个类有哪些成员

3、类的相互调用关系

------- android培训java培训、期待与您交流!
----------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: