美文网首页
④Java.IO

④Java.IO

作者: 牧师Harray | 来源:发表于2015-06-30 16:09 被阅读157次

    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

          本文链接:https://www.haomeiwen.com/subject/nuueqttx.html