Java之IO与File操作
对于java中的io与文件一直很模糊,今天有时间就整理了一下
为了弄清关系,做了张图,感觉舒服多了:
其中InputStream和OutputStream都是抽象类,没有具体的实现,其中最常用的方法是read()、write()、flush()和close()方法,养成close()的好习惯不错的
1、FileInputStream&FileOutputStream的用法
这两个类是比较常用的,贴个代码用法注释的很详细了:
File f = new File("test.txt");
try {
//OutputStream可以接受File对象也可以直接接受路径
FileOutputStream fos = new FileOutputStream(f);
//writer跟reader是用来写入或读出流内容的
OutputStreamWriter writer = new OutputStreamWriter(fos);
writer.write("hey ");
writer.write("baby");
//刷新缓冲并关闭输出流
writer.flush();
writer.close();
fos.close();
FileInputStream fis = new FileInputStream("test.txt");
InputStreamReader reader = new InputStreamReader(fis,"UTF-8");
//available方法返回流中的字节数
int size = fis.available();
if(size>0){
//StringBuffer是一个字符串缓冲区,它的append方法很好用
StringBuffer sb = new StringBuffer();
while(reader.ready()){
sb.append((char)reader.read());
}
System.out.println(sb.toString());
}
//不要忘了关闭stream
reader.close();
fis.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
2、
FilterInputStream&FilterOutputStream&组合流过滤器
1、DataInputStream&DataOutputStream
DataInputStream实现了DataInput接口,可以从流中读出或写入指定类型的数据,下面用一个例子说明一下从文件流中读出数字:
File f = new File("test.txt");
try {
FileInputStream fis = new FileInputStream(f);
//以一个输入流作为参数
DataInputStream dis = new DataInputStream(fis);
double d = dis.readDouble();
System.out.println("here is "+d);
fis.close();
dis.close();
//如果想用缓冲区的话,可以这样:
DataInputStream dis1 = new DataInputStream(new BufferedInputStream(new FileInputStream(f)));
double d1 = dis1.readDouble();
System.out.println("here1 is "+d1);
dis1.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
2、BufferedInputStream&BufferedOutputStream
用法上面的一个程序提到了,目的是建立一个带缓冲区的流,在从流中读入字符或写入字符时不会每次都对设备进行访问,而是写入缓冲区或从缓冲区读入,当缓冲区为空或写满之后再操作设备。
3、PushbackInputStream
可以构建一个可以预览一个字节或具有指定尺寸的回推缓冲区的流,即可以提前一步知道要读入的字节,然后根据是否需要决定是否留下,如果不需要则可以调用unread()方法将其推回流中,其用法跟DataInputStream一样,不再列举。
3、ZIP文档
ZIP文件系统主要由四个类构成:
- ZipInputStream 接受一个InputStream对象作为构造器参数
- ZipOutputStream 接受一个OutputStream对象作为构造器参数
- ZipEntry 接受一个String类型作为构造器参数,是指Zip中的一个项
- ZipFile 接受一个String类型或者File对象作为构造器参数,用于从其中读入数据
用代码说明:
4、java对象流与序列化
FileOutputStream fos; try { fos = new FileOutputStream("test.zip"); ZipOutputStream zos = new ZipOutputStream(fos); //创建一个新的zip项,对于要压缩的所有文件都执行此操作并放入zos流中 ZipEntry ze = new ZipEntry("test.txt"); zos.putNextEntry(ze); //不要忘记关闭流 zos.closeEntry(); zos.close(); FileInputStream fis = new FileInputStream("test.zip"); ZipInputStream zis = new ZipInputStream(fis); ZipEntry entry; while((entry = zis.getNextEntry())!=null){ System.out.println("entry's size is "+entry.getSize()); System.out.println("entry's name is "+entry.getName()); } zis.closeEntry(); zis.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
其实就是将对象保存到文件中然后可以从文件中原样读取对象,主要有两个类来实现:
- ObjectOutputStream(OutputStream out) 调用writeObject(Object obj)将对象写入指定的流中
- ObjectInputStream(InputStreamin) 调用ReadObject()将对象从指定流中读出
很简单吧,看个程序就会了:
package com.kexin.stream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/**
* Java对象流与序列化
* @author KeXin
*
*/
public class InputOutput {
public static void main(String[] args) {
Person p1 = new Person("Tom","boy",12);
Person p2 = new Person("KaiLi","girl",11);
FileOutputStream fos;
try {
fos = new FileOutputStream("test.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(p1);
oos.writeObject(p2);
oos.close();
fos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test.txt"));
Person person;
while((person = (Person)ois.readObject())!=null){
System.out.println("This one's name is "+person.getName());
}
ois.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//所有想要序列化的类必须得继承Serializable接口,但不需要实现什么,而且可以通过声明serialVersionUID来控制版本
class Person implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
public String name;
public String sex;
public int age;
public Person(String name, String sex, int age) {
super();
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
5、File使用
之前没整理过这一块,总觉得内容很多,看了看其实没多少,就对目录的操作,对文件的操作,都是基本的操作:create、delete、copy、cut等,就不写了,睡觉