java.IO包是java处理文件目录有关的工具包,对于本节的学习,我们要有以下几个目标
- 了解java.io包
- 运用File类对文件或者目录的属性进行操作
- 理解流,理解输入输出流的概念
- 运用FileInputStream类和FileOutputStream类读、写字节文件
- 运用FileReader类和FileWriter类配合BufferedReader类和BufferedWriter类读、写字符文件。
- 使用BufferedReader类从控制台接受输入
- 运用DataInputStream类和DataOutputStream类读写数据文件
这里十分感谢:http://blog.csdn.net/nisior/article/details/7162754
首先来了解File类
顾名思义看来,就是文件,这个类包含了文件的属性包括路径、名称、大小等等,如果在处理文件的时候需要用到某种属性或者方法,一定要到File类来看看是否有你想要的东西。
注:学习应该也是应该以网络的形式展开,你需要做的是拓展网络节点的个数,每个节点代表了一个知识点,实践的时候再去拓展这个节点,形成一个子网络。
至于File类中的方法,希望诸君不要像我一样偷懒,一定要浏览一遍。这里举个例子以飨读者:
public class FileDemo
{
public static void main(String[] args)
{
//创建一个文件对象,使之与一个文件关联
File file = new File("File.txt");
//显示与文件有关的属性信息
System.out.println("文件或目录是否存在:" + file.exists());
System.out.println("是文件吗:" + file.isFile());
System.out.println("是目录吗:" + file.isDirectory());
System.out.println("名称:" + file.getName());
System.out.println("绝对路径:" + file.getAbsolutePath());
System.out.println("文件大小:" + file.length());
}
}
再来看看流的概念
流是指一连串流动的数据信号,是以先进先出的方式发送和接收数据的通道。
根据流动的方向,分为输入流和输出流
根据文件的大小,分为字节流和字符流
字节流:是指8位的通用字节流,以字节为基本单位,对字节流进行操作的类大多继承于InputStream和OutputStream类。
字符流:是指16位的Unicode字符流,以字符(两个字节)为基本单位,非常适合处理字符串和文本,大部分继承自Reader类和Writer类。
下面我们来看看这个包中最常见的方法,也是你们今后用到的最频繁的方法:
使用FileInputStream类读文件
- FileInputStream类成为文件输入流,继承于InputStream类,是文件操作的最基本的类
- 它的作用是将文件中的数据输入到内存中,我们可以利用它来读文件
- 由于它属于字节流,因此在读取Unicode字符(如中文)的文件时候可能会出现问题
使用FileOutputStream类写文件
- 继承自OutputStream类,可以利用它来写文件。
一般来讲,这两个类的使用是成对出现的,采用字节来处理文件,好处就在于,不必考虑数据格式的问题,虽然在编码上稍微复杂了一些,但是当文件过大的时候,效率就体现出来了。
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
File srcFile = new File("src.dat"); //源文件对象
File destFile = new File("dest.dat"); //目标文件对象
if (!(destFile.exists())) { //判断目标文件是否存在
destFile.createNewFile(); //如果不存在则创建新文件
}
//使用源文件对象创建文件输入流对象
FileInputStream fis = new FileInputStream(srcFile);
//使用目标文件对象创建文件输出流对象
FileOutputStream fos = new FileOutputStream(destFile);
byte[] buf = new byte[1024]; //创建字节数组,作为临时缓冲
System.out.println("开始复制文件...");
while (fis.read(buf) != -1) { //循环从文件输入流中读取数据
fos.write(buf); //写入到文件输出流中
}
System.out.println("文件复制成功!");
fis.close(); //关闭流
fos.close();
}
}
字符流
• FileInputStram类和FileOutputStream类虽然可以高效率地读/写文件,但对于Unicode编码的文件,使用它们有可能出现乱码;
• 考虑到Java是跨平台的语言,要经常操作Unicode编码的文件,使用字符流操作文件是有必要的;
• 使用字符流将涉及到以下4个类:
FileReader类和FileWriter类;
BufferedReader类和BufferedWriter类。
这四个类你非常容易用到,不要再被各种名称搞混淆,其核心就这么几句话:
读写类要用Buffer类包装,任何的读写都要设置缓存才能实现高效。
可以将这段代码作为例子仔细的研读一番
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Test11 {
public static void main(String[] args) throws IOException {
String s="abcd中国家@#$%"+System.getProperty("line.separator")+"asdfsdf顺右面";
Test11 t=new Test11();
t.writeFile(s);
t.readFile();
}
public void readFile() throws IOException{
File f=new File("r:\\io\\reader.doc");
FileReader fr=new FileReader(f);
BufferedReader br=new BufferedReader(fr);
String ss=null;
while((ss=br.readLine())!=null){
System.out.println(ss);
}
br.close();
fr.close();
}
public void writeFile(String s) throws IOException{
File f=new File("r:\\io\\reader.doc");
FileWriter fr=new FileWriter(f);
BufferedWriter br=new BufferedWriter(fr);
br.write(s);
br.close();
fr.close();
}
}
到目前位置我们已经介绍了两种流,字符和字节,这两种流之间还有过渡流,即:
InputStreamReader, InputStreamWriter
他们是字节流和字符流的桥梁,作用是人为的操作格式编码。
设想这么一种情况:
当你使用System.in 从控制台接受输入的时候,由于in是一个InputStream类型的对象,所以你每一次只能从控制台输入一个字节才不会引起错误,所以必须对in进行处理,才可以顺利的从控制台接受输出,所以将使用:
InputStreamReader
BufferedReader
•可以使用它来转换System.in,如:
InputStreamReader isr = new InputStreamReader(System.in);
•这样的字符流效率很低,再使用BufferedReader类来为其建立缓冲,如:
BufferedReader br = new BufferedReader(isr);
•这样,就可以从控制台接受输入了。
基本数据类型的读/写
•FileInputStream和FileOutputStream在读写文件时不考虑数据的类型;
•FileWriter和FileReader在读写文件时,将所有的数据都看做字符;
•有时候,我们需要将各种类型的数据写入文件或是从文件中读取,
DataInputStream类和DataOutputStream类可以满足需要。
但是它们不能单独使用,需要配合别的字节流一起使用。
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class Test8 {
public static void main(String[] args) throws Exception {
File f = new File("r:\\io\\dat.dat");
FileOutputStream fos = new FileOutputStream(f);
DataOutputStream dos = new DataOutputStream(fos);
dos.write(22);
dos.writeBoolean(true);
dos.writeChar('a');
dos.writeUTF("abc中国家####");
dos.close();
fos.close();
FileInputStream fis=new FileInputStream(f);
DataInputStream dis=new DataInputStream(fis);
System.out.println( dis.read());
System.out.println( dis.readBoolean());
}
}
ObjectInputStream ObjectOutputStream
作用:用来处理Object对象的流,能将原来只能存于VM中的对象存入到我们要求的储存介质中去,可以用来做数据缓存。
处理的对象都必须实现Serializable,transiant关键字来修饰无需序列化的属性
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Test9 {
public static void main(String[] args) throws Exception {
File f = new File("r:\\io\\dat2.dat");
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream dos = new ObjectOutputStream(fos);
Person p=new Person("yy",22);
dos.writeObject(p);
dos.close();
fos.close();
FileInputStream fis=new FileInputStream(f);
ObjectInputStream ois=new ObjectInputStream(fis);
Person ps=(Person)ois.readObject();
System.out.println(ps.getName()+"\t"+ps.getId());
}
}
class Person implements Serializable{
private String name;
private transient int id;
public Person() {
super();
}
public Person(String name, int id) {
super();
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
RandomAccessFile:随机文件读取
使用场景:支持对随机访问文件的读取和写入
特点:
类中既有读方法也有写方法
必须指定访问文件模式
-
seek()和skip()
示例:操作日志import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test10 {
public static void main(String[] args) throws IOException {
BankAccount ba=new BankAccount(1000);
for(int i=0;i<10;i++){
ba.withDrawal(100);
}
}
}
class BankAccount{
private int money;
public BankAccount(int money){
this.money=money;
}
public void withDrawal(int money) throws IOException{
this.money=this.money-money;
log("您取了"+money+",账户余额:"+this.money);
}
private void log(String string) throws IOException {
File f=new File("r:\\io\\log.txt");
RandomAccessFile raf=new RandomAccessFile(f,"rwd");
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日");
Date d=new Date();
String dd=sdf.format(d);
raf.seek(raf.length());
String s="\r\n"+dd+"\t"+string;
raf.write(s.getBytes("gbk"));
raf.close();
}
}
总结
• java.io包是Java内置的包,其中包含一系列对输入/输出进行操作的类;
• File类的对象可以访问文件(或目录)的属性,但不可以进行读/写操作;
• 从方向上讲,流分为输入流和输出流,但从格式上区分的话,流分为字节流和字符流;
• 使用FileInputStream类和FileOutputStream类以字节流方式对文件进行读/写操作,这是操作文件最基本的两个类;
• FileReader类和FileWriter类配合BufferedReader类和BufferedWriter类可以以字符流方式对文件进行读/写操作;
• 从控制台接受输入要使用到InputStreamReader类和BufferedReader类;
• DataInputStream类和DataOutputStream类允许读/写各种基本数据类型;
• 绝大部分的IO操作都可能抛出IOException。