④Java.IO

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。

你可能感兴趣的:(④Java.IO)