JAVA的I/O介绍。<<疯狂JAVA编程>>第15章有详细介绍,如下:
http://www.cnblogs.com/lijunamneg/archive/2013/03/22/2975087.html
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 流
* 流可以读写很多设备,但是读写操作是规范的.
* 流根据方向分为:
* 输入流:输入流用于"读",将数据从外界设备读入程序
* 输出流:输出流用于"写",将数据发送到外界设备
*
* 流还可以分为:
* 节点流(低级流):数据源明确,真实负责读写数据的流
* 处理流(高级流):不能独立存在,需要基于其他流进行处理工作,使用高级流的目的是简化读写操作
*
* 使用文件流与RandomAccessFile读写文件的区别:
* RAF是基于指针进行读写文件数据的,所以可以操作指针位置随意读写文件任何位置的数据.
* 文件流是基于流的形式读写文件数据,所以只能按顺序读写文件数据,
* 且不能返回去重新读写,除非重新创建流进行.
*
* java.io.FileOutputStream
* 文件字节输出流,是一个低级流,负责向文件中写出数据.
* @author Romanceling
*
*/
public class FOSTest{
public static void main(String[] args) throws IOException {
/*
* 默认创建出来的FOS是覆盖操作,即:
* 当创建好该留针对某文件进行写操作前,流会将该文件所有数据删除.
* 只有本次通过该流写出的数据会存于该文件中.
*/
FileOutputStream fos = new FileOutputStream("fos.txt");
String str = "我爱北京天安门!";
byte[] data = str.getBytes("UTF-8");
fos.write(data);
System.out.println("写出完毕!");
/*
* FOS的构造方法支持第二个参数,是一个boolean值,若为true,则是追加写模式.
* 通过该流写出的数据会在该文件末尾追加.
*/
FileOutputStream fos= new FileOutputStream("fos.txt",true);
String str = "天安门上太阳升!";
fos.write(str.getBytes("UTF-8"));
System.out.println("写出完毕!");
//释放资源
fos.close();
}
}
/**
* java.io.FileInputStream
* 文件字节输入流
* 是一个低级流,作用是从文件中读取字节数据
* @author Romanceling
*
*/
public class FISTest{
public static void main(String[] args) throws IOException {
FileInputStream fis= new FileInputStream("fos.txt");
byte[] data = new byte[100];
int len = fis.read(data);
String str = new String(data,0,len,"UTF-8");
System.out.println(str);
fis.close();
}
}
/**
* 使用文件字节输入输出流实现文件复制
* @author Romanceling
*/
public class CopyTest1 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("music.mp3");
FileOutputStream fos = new FileOutputStream("muisc_copy.mp3");
int len = -1;
byte[] data = new byte[1024*10];
while((len=fis.read(data))!=-1){
fos.write(data,0,len);
}
System.out.println("复制完毕!");
fis.close();
fos.close();
}
}/**
* java.io.BufferedOutputStream 缓冲输出流 用于写出数据
* java.io.BufferedInputStream 缓冲输入流 用于读取数据
* 使用缓冲输入流和缓冲输出流实现文件复制
* @author Romanceling
*
*/
public class CopyTest2 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("bos.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("bos_copy.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
/* void flush();
* 强制将缓冲区内容写出,无论缓冲区是否装满(各种缓冲流的close方法内部带有flush)
*/
bos.flush();
int d = -1;
long start = System.currentTimeMillis();
/*
* 缓冲流读取字节:
* 当调用bis.read()方法读取一个字节时,缓冲流会一次性读取若干字节回来,
*并存入内部维护的一个字节数组中,然后将第一个字节返回,
* 当再次调用该方法读取一个字节时,会直接将字节数组中下一个字节返回,
* 而不是再去读取数据,直到字节数组所有字节全部返回后才会再一次性读取一组字节回来.
* 所以实际上还是提高了读取数据量减少读取次数提高的读取效率.
*/
while((d = bis.read())!=-1){
bos.write(d);
}
long end = System.currentTimeMillis();
System.out.println("复制完毕!耗时:"+(end-start)+"ms");
bis.close();
bos.close();
}
}
/**
* 字符流
* 字符流读写数据的单位是字符.但是底层依然是读写字节
* 所以字符流都是高级流,使用它们可以方便读写文本数据.
*
* OutputStreamWriter
* 该字符输出流的特点是可以按照指定的字符集写出字符
* @author Romanceling
*/
public class OSWTest {
public static void main(String[] args) throws IOException {
FileOutputStream fos= new FileOutputStream("osw.txt");
/*
* 默认创建的字符输出流是按照当前系统默认的字符集将写出的字符串转换为对应的字节.
*/
// OutputStreamWriter osw = new OutputStreamWriter(fos);
/*
* 也可以按照指定的字符集写出字符串.
*/
OutputStreamWriter osw= new OutputStreamWriter(fos,"UTF-8");
osw.write("摩擦摩擦,似魔鬼的步伐");
/**
* java.io.InputStremReader
* 字符输入流,可以按照指定的字符集读取字符
*/
FileInputStream fis = new FileInputStream("osw.txt");
InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
int d = -1;
while((d=isr.read())!=-1){
System.out.print((char)d);
}
isr.close();
osw.close();
}
}
/**
* java.io.PrintWriter
* 缓冲字符输出流
* 特点:可以按行写出字符串.并且带有自动行刷新功能
* 通常创建PrintWriter时,其内部会自行创建一个高级流BufferedWriter作为缓冲功能.
*
* java.io.BufferedWriter
* 缓冲字符输出流
* @author Romanceling
*
*/
public class PWDTest {
public static void main(String[] args) throws IOException {
/*
* 针对文件写出操作的构造方法:
* PrintWriter(File file)
* PrintWriter(String path)
*/
PrintWriter pw = new PrintWriter("pw.txt","UTF-8");
pw.println("大家好");
/**
* PrintWriter可以直接处理字节流,也可以处理字符流
* 但是,直接处理字节流是时不能指定字符集!
*/
FileOutputStream fos = new FileOutputStream("pw1.txt");
//直接处理字节流不能指定字符集,只能用系统默认
// PrintWriter pw = new PrintWriter(fos);
//中间添加一层OSW可以指定字符集了.
OutputStreamWriter osw= new OutputStreamWriter(fos,"UTF-8");
PrintWriter pw = new PrintWriter(osw);
pw.println("哈哈哈");
/**
* 当创建PrintWriter时处理的是流(字节字符均可)
* 就可以创建具有自动行刷新功能的.
* 自动行刷新:每当使用println方法写出字符串时,会自动flush
*/
/*
* 当创建PW时第一个参数为流时,就支持第二个参数,
* 该参数是一个boolean值,若为true,则PW具有自动行刷新
*/
PrintWriter pw = new PrintWriter(fos,true);
/*
* 具有自动行刷新功能的PW在使用println方法写出字符串时会自动进行flush.
* 注意,print方法写出字符串不会进行flush.
*/
pw.println("你好!");
pw.close();
}
}
/**
* java.io.BufferedReader
* 缓冲字符输入流,可以按行读取字符串
* @author Romanceling
*
*/
public class BRTest {
public static void main(String[] args) throws IOException {
FileInputStream fis= new FileInputStream( "src"+File.separator+
"day08"+File.separator+"BRDemo.java");
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
/*
* BufferedReader提供方法:
* String readLine()
* 该方法会连续读取若干字节,直到读取到换行符为止,然后将换行符之前的所有字符
* 组成一个字符串后返回,但是返回的字符串中不含有最后的换行符.
* 当读取到文件末尾,返回值为NULL.
*/
String line = null;
while((line = br.readLine())!=null){
System.out.println(line);
}
br.close();
}
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
/**
* java.io.ObjectOutputStream
* 对象输出流,是一个高级流,使用该流可以很方便的
* 将java中的对象转换为一组字节后写出.
* @author Administrator
*
*/
public class OOSTest {
public static void main(String[] args) throws IOException {
/*
* 将Person类的一个实例写入到person.obj文件中保存.
*/
Person p = new Person();
p.setName("范老师");
p.setAge(24);
p.setGender("男");
List<String> otherInfo
= new ArrayList<String>();
otherInfo.add("是一名段子手");
p.setOtherInfo(otherInfo);
System.out.println(p);
FileOutputStream fos = new FileOutputStream( "person.obj" );
ObjectOutputStream oos = new ObjectOutputStream(fos);
/*
* OOS提供的写出对象的方法,该方法:
* 将给定的对象装换位一组字节后写出.
*
* 调用writeObject方法后,首先将p对象转换为了一组字节,
* 将对象转换为一组字节的过程称为:对象的序列化
* 然后将这组字节通过fos写入到文件中的过程称为:持久化
*/
oos.writeObject(p);
System.out.println("写出完毕!");
oos.close();
}
}
/**
* java.io.ObjectInputStream
* 对象输入流,是一个高级流,可以读取一组字节然后将其还原为对象.
* 读取的字节应当是由ObjectOutputStream将对象转换的.
* @author Romanceling
*
*/
public class OISTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream("person.obj");
ObjectInputStream ois = new ObjectInputStream(fis);
/*
* 将一组字节还原回对象的过程称为:对象反序列化
*/
Person p = (Person)ois.readObject();
System.out.println(p);
ois.close();
}
}
/**
* 该类是用于测试对象流的读写对象操作
* 若一个类需要被ObjectOutputStream写出,该类必须实现接口Serializable
* @author Romanceling
*
*/
public class Person implements Serializable {
/**
* 当一个类实现了序列化接口后,应当定义一个常量表示版本号.
* 版本号对对象的反序列化结果产生直接影响.
*
* 对象在进行序列化时,会将版本号信息也加入到字节中,
* 若我们没有定义版本号,对象输出流会根据当前类的结构生成一个版本号,
* 只要当前类的属性没有发生过结构上的变化,版本号是不变的.
* 但是建议将版本号自行定义出来,以便维护.
*
* 对象输入流ObjectInputStream在反序列化对象时,会检查该对象的版本号与当前类版本号
* 是否一致。 若字节中该对象的版本号与当前类版本号一致,反序列化成功.
* 就算类的结构发生了变化,也一样可以成功.
* 但是若版本号不一致,那么反序列化时会抛出异常.
*/
private static final long serialVersionUID = 1L;
/*
* 当前类若想序列化,除了当前类需要实现序列化接口外,引用类型的属性都要实现序列化接口.
* java API提供的类基本都实现了.例如下面使用的String.
*/
private String name;
private int age;
private String gender;
/*
* transient关键字修饰的属性的作用:
* 当前对象在进行序列化时,该属性的值将被忽略.
*/
private transient List<String> otherInfo;
public Person(){
}
public Person(String name, int age, String gender, List<String> otherInfo) {
super();
this.name = name;
this.age = age;
this.gender = gender;
this.otherInfo = otherInfo;
}
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;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public List<String> getOtherInfo() {
return otherInfo;
}
public void setOtherInfo(List<String> otherInfo) {
this.otherInfo = otherInfo;
}
public String toString(){
return name+","+age+","+
gender+","+otherInfo;
}
}