Java流的分类
1.输入/输出流
输入流:只能向其读数据,不能写。
输出流:只能向其写数据,不能读。
所谓的输入输出都是相对应用程序而言的。
2.字节流/字符流
单位不同,字节流操作8位,字符流操作16位,2倍关系。
3.节点流/处理流
按照流的角色来分的。
节点流:从/向特定的IO设备读/写的流,也称低级流。
处理流:对于一个已经存在的流进行连接或包装,通过包装后的流来实现读写功能,也称高级流。
Java流概念模型
Java.io包里面有40多个类,看上去很凌乱负责,但实际有规律。所有类都继承自4个类,
InputStream |
OutputStream |
Reader |
Writer |
所有类的结构图如下:
其实是按字节流/字符流来分的。
上述4个类是抽象类的主要方法。
读,InputStream/Reader
有几个主要的方法:
Int read()读取单个字节/字符。
Int read(byte[] b/char[] c),读取给定数组的字节/字符。
Int read(byte[] b/char[] c, int off, int len)从字节/字符组中的off位置,读取len长度。
代码:
以FileInputStream和FileReader为例子:
public static void main(String[] args) throws Exception{ // TODO Auto-generated method stub FileInputStream fis = new FileInputStream("TestFile1.java"); byte[] bbuf = new byte[1024]; int hasRead = 0; while((hasRead = fis.read(bbuf))>0){ System.out.print(new String(bbuf,0,hasRead)); } fis.close(); }
这里byte数组的大小是1024,如果很小,或者为奇数的话,可能会出现读出来的是乱码。
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
try {
fr = new FileReader("TestFile1.java");
char[] cbuf = new char[32];
int hasRead = 0;
while ((hasRead = fr.read(cbuf)) > 0) {
System.out.print(new String(cbuf, 0, hasRead));
}
} catch (IOException e) {
e.printStackTrace();
}
finally{
fr.close();
}
}
写,OutputStream/Writer
主要的方法:
Void write(c)写入指定的c个字节/字符。
Void write(byte[] b/char[] c)写入字节/字符数组中的数据。
Void write(byte[]/char[] buf, int off, int len)从字节/字符数组中的off位置写入len长度到输出流。
由于字符流以字符为单位,Writer可以用字符串来代替字符数组,于是有了2个新的方法:
Void write(string s)写入字符串s到流。
Void write(string s, int off, int len)从字符串s的off位置处写入len长度到流。
以FileOutputStream和FileWriter为例子:
public static void main(String[] args) throws IOException { // TODO Auto-generated method stub FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream( " TestFile1.java"); fos = new FileOutputStream( " NewFile.txt"); byte[] bbuf = new byte[1024]; int hasRead = 0; while ((hasRead = fis.read(bbuf)) > 0) { fos.write(bbuf, 0, hasRead); } } catch (IOException e) { e.printStackTrace(); } finally { fis.close(); fos.close(); } }
FileWriter:
public static void main(String[] args) throws IOException { // TODO Auto-generated method stub FileWriter fw = null; try { fw = new FileWriter("newFile2.txt"); fw.write("静夜思\r\n"); fw.write("床前明月光,\r\n"); fw.write("疑是地上霜,\r\n"); fw.write("举头望明月,\r\n"); fw.write("低头思故乡。\r\n"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ fw.close(); } }
Java序列化和反序列化
序列化即将对象转换成数据(二进制或xml文本),反序列化则相反。
Java序列化/反序列化用到的类:ObjectOutputStream/ObjectInputStream,它们都是处理流对象,接受节点流FileOutputStream/FileInputStream.
序列化/反序列化要求被处理的类继承Serializable接口。
例子:
//Person 类
public class Person implements java.io.Serializable { public String Name; public int Age; public Person(String name,int age){
this.Name=name;
this.Age=age;
}
} public class TestSerialization { /**
* @param args
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws ClassNotFoundException {
// TODO Auto-generated method stub /**
* Serialize
*/
try {
ObjectOutputStream op = new ObjectOutputStream(
new FileOutputStream(
"Person.txt"));
Person p = new Person("Jackson", 24);
Person p2 = new Person("Anne", 23);
op.writeObject(p);
op.writeObject(p2);
System.out.println("person info: name is " + p.Name + " ;age is: "
+ p.Age);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} /**
* DeSerialize
*/
try {
ObjectInputStream ip = new ObjectInputStream(new FileInputStream(
"Person.txt"));
Person p = (Person) ip.readObject();
Object o;
while ((o = ip.readObject()) != null) {
Person pp = (Person) o;
System.out.println("name: " + pp.Name + ",Age:" + pp.Age);
} } catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}