Java程序设计(高级及专题)- IO流与序列化

  • 今天我们讲讲I/O流与序列化的问题?
    个人理解:在我们在编程开发的时候,往往会涉及到文件的读取与写入,而java为我们提供的I/O流就是用来解决这个问题的。我们在读取和写入文件的时候,都会涉及到序列化的东西,谈到序列化就离不开编码格式,我们的windows是用GBK来编码的而我们的Java通常是用UTF-8来编码的,所以我们有时候开发会遇到乱码的问题,此时我们不要慌,问题总是会能解决的,大不了从新来吗;哪么我们回过头来看看I/O,它有五类一接口一关键字,分别是InputStream字节输入流(文件写入)、OutputStream字节输出流(文件读取)、Reader字符输入流(文件写入)、Writer字符输出流(文件读取)、File文件类(文件路径)和Serializable标识接口(序列化的标准)以及transient(反序列化关键字);一个字符等于两个字节,字符流能处理的字节流都能处理,字符流不一定能够处理字节流的事物。

File类

/*
File读取文件的三种方式(第三种常用)
	File.separator  可以看成  //
	从盘符开始写,是绝对路径 如:e:\\work\\workspace\\ioDemo\\txt\\aaa.txt
	直接写是相对路径,相对工程下的.classpath文件
	f1.createNewFile();只能新建一个文件,不能新建文件夹
	file.list();//该方法只能得到该目录下子目录的文件名的String集合
*/
       File f=new File("D:"+File.separator+"aaa"+File.separator+"aaa.txt");
		/*
		File f1=new File("D:"+File.separator+"aaa","aaa.txt");
		
		File parent=new File("D:"+File.separator+"aaa");
		File child=new File(parent,"aaa.txt");*/

下面是它的一些方法:

序号 方法 介绍
1 public String getName() 返回由此抽象路径名表示的文件或目录的名称。
2 public String getParent() 返回此抽象路径名的父路径名的路径名字符串,如果此路径名没有指定父目录,则返回 null。
3 public File getParentFile() 返回此抽象路径名的父路径名的抽象路径名,如果此路径名没有指定父目录,则返回 null。
4 public String getPath() 将此抽象路径名转换为一个路径名字符串。
5 public boolean isAbsolute() 测试此抽象路径名是否为绝对路径名。
6 public String getAbsolutePath() 返回抽象路径名的绝对路径名字符串。
7 public boolean canRead() 测试应用程序是否可以读取此抽象路径名表示的文件。
8 public boolean canWrite() 测试应用程序是否可以修改此抽象路径名表示的文件。
9 public boolean exists() 测试此抽象路径名表示的文件或目录是否存在。
10 public boolean isDirectory() 测试此抽象路径名表示的文件是否是一个目录。
11 public boolean isFile() 测试此抽象路径名表示的文件是否是一个标准文件。
12 public long lastModified() 返回此抽象路径名表示的文件最后一次被修改的时间。
13 public long length() 返回由此抽象路径名表示的文件的长度。
14 public boolean createNewFile() throws IOException 当且仅当不存在具有此抽象路径名指定的名称的文件时,原子地创建由此抽象路径名指定的一个新的空文件。
15 public boolean delete() 删除此抽象路径名表示的文件或目录。
16 public void deleteOnExit() 在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。
17 public String[] list() 返回由此抽象路径名所表示的目录中的文件和目录的名称所组成字符串数组。
18 public String[] list(FilenameFilter filter) 返回由包含在目录中的文件和目录的名称所组成的字符串数组,这一目录是通过满足指定过滤器的抽象路径名来表示的。
19 public File[] listFiles() 返回一个抽象路径名数组,这些路径名表示此抽象路径名所表示目录中的文件。
20 public File[] listFiles(FileFilter filter) 返回表示此抽象路径名所表示目录中的文件和目录的抽象路径名数组,这些路径名满足特定过滤器。
21 public boolean mkdir() 创建此抽象路径名指定的目录。
22 public boolean mkdirs() 创建此抽象路径名指定的目录,包括创建必需但不存在的父目录。
23 public boolean renameTo(File dest) 重新命名此抽象路径名表示的文件。
24 public boolean setLastModified(long time) 设置由此抽象路径名所指定的文件或目录的最后一次修改时间。
25 public boolean setReadOnly() 标记此抽象路径名指定的文件或目录,以便只可对其进行读操作。
26 public static File createTempFile(String prefix, String suffix, File directory) throws IOException 在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。
27 public static File createTempFile(String prefix, String suffix) throws IOException 在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。
28 public int compareTo(File pathname) 按字母顺序比较两个抽象路径名。
29 public int compareTo(Object o) 按字母顺序比较抽象路径名与给定对象。
30 public boolean equals(Object obj) 测试此抽象路径名与给定对象是否相等。
31 public String toString() 返回此抽象路径名的路径名字符串。

InputStream 字节输入流

package com.gaoji.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
//输入字节流
public class IOdome_03 {
    //读取字节流InputStream
    public static void main(String[] args) throws IOException   {
        File f1 = new File("D://");//目标文件夹
        File f2 = new File(f1, "aaa.txt");//目标文件
        
        InputStream in =null;
        try {
            in = new FileInputStream(f2);//对该流进行实例化赋值
            int a = 0;//用于介绍流中独处的内容
//            in.skip(1);//跳过n个字节不读
//            第一种方法
//            while ((a=in.read())!=-1) {
//                System.out.print((char)a);
//            }
//          第二种方法(比较耗内存,速度会变快)
            byte[] bs = new byte[in.available()];
            while ((a=in.read())!=-1) {
                for(int i=0;i<bs.length;i++){
                    if(bs[i]==0){
                        break;
                    }
                }
                System.out.print((char)a);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            in.close();
        }
    }
}

OutputStream 字节输出流

package com.gaoji.io;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
//输出字节流
public class IOdome_04 {
    //写入字节流OutputStream
    public static void main(String[] args) throws IOException {
        File f1 = new File("D://");//目标文件夹
        File f2 = new File(f1, "aaa.txt");//目标文件
        OutputStream out=null;
        try {
            out=new FileOutputStream(f2,true);//true是续写,false是重写
            String a="holle wrold1";
//           一个字节一个字节的写
//            byte[] bs=a.getBytes();
//            for (int i = 0; i < bs.length; i++) {
//                out.write(bs[i]);
//            }
//            一个数组的写
            out.write(a.getBytes());
        } catch (Exception e) {
            // TODO: handle exception
        }finally {
            out.flush();//刷新(字节流是自动刷新的,不过不写不规范)
            out.close();//关闭
        } 
    }
}

Reader 字符输入流

//读
    public static void reader() {
        try {
            InputStreamReader fr=new InputStreamReader(new FileInputStream(new File("D:\\aaa.txt")),"utf-8");
            char[] cs=new char[6];
            fr.read(cs);
            System.out.println(new String(cs));
            System.out.println(fr.getEncoding());
            fr.close();
    } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
    }
        
    }

Writer 字符输出流

在使用字节输出流可以不刷新文件流,系统会自动刷新,而字符输出流不一样,如果不刷新再关闭的话,文件不会有任何操作的。

//写
    public static void writer() {
        OutputStreamWriter ows = null;
        try {
            ows = new OutputStreamWriter(new FileOutputStream(new File("D://aaa.txt")), "gbk");
            String a = "今天天气不错";
            ows.write(a);
            System.out.println(ows.getEncoding());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                ows.flush();
                ows.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

序列化与反序列化

  • User.java User实体类
package com.gaoji.io;

import java.io.Serializable;
//IO流里面的接口 Serializable
public class User implements Serializable {

    /**
     * 序列化编译id
     * transient //被他修饰的字段不会被序列化
     */
    private static final long serialVersionUID = 4950216177746797393L;
    private int id;
    private String name;
    private char sex;
    private transient String phone;
    public User(int id, String name, char sex, String phone) {
        super();
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.phone = phone;
    }
    public User() {
        super();
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public char getSex() {
        return sex;
    }
    public void setSex(char sex) {
        this.sex = sex;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", sex=" + sex + ", phone=" + phone + "]";
    }
}

  • Run.java 序列化运行类
package com.gaoji.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
//对象的序列化与反序列化
public class IOdome_07 {

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        xlh();
        fxlh();

    }
    //对象序列化
    public static void xlh() throws FileNotFoundException, IOException {
        User u = new User(1, "张三", '男', "15665620000");
        ObjectOutputStream out = null;
        try {
            out = new ObjectOutputStream(new FileOutputStream(new File("d:\\user.dat")));
            out.writeObject(u);
            System.out.println(u);
        } finally {
            out.flush();//刷新
            out.close();//关闭
        }
    }
    //对象反序列化
    public static void fxlh() throws IOException, ClassNotFoundException {
        ObjectInputStream in = null;
        try {
            in = new ObjectInputStream(new FileInputStream(new File("d:\\user.dat")));
            User u = (User) in.readObject();
            System.out.println(u.toString());
        } finally {
            in.close();
        }
    }

}

文件流实现复制

  • 字节流实现
//字节流 FileInputStream和FileOutputStream实现
    public static void InputOutputStream() throws IOException {
        File f1 = new File("D://");
        File f2 = new File(f1, "qqq.jpg");

        File f3 = new File("C://");
        File f4 = new File(f3, "qqq.jpg");

        FileInputStream fis = new FileInputStream(f2);//输入类(读取)
        FileOutputStream fos = new FileOutputStream(f4);//输出类(写入)
        int len = 0;
        while ((len = fis.read()) != -1) {
            fos.write(len);
        }
        fos.flush();
        fos.close();
        fis.close();
    }
  • 字符流实现
//缓存字节流 BufferedInputStream和BufferedOutputStream实现
    public static void BufferedInputOutputStream() throws IOException {
        // TODO Auto-generated method stub
        File f1 = new File("D://");
        File f2 = new File(f1, "qqq.jpg");
        File f3 = new File("C://");
        File f4 = new File(f3, "qqq.jpg");
        BufferedInputStream bin = null;
        BufferedOutputStream out = null;
        try {
            byte[] bs = new byte[1024];
            bin = new BufferedInputStream(new FileInputStream(f2));
            out = new BufferedOutputStream(new FileOutputStream(f4));
            while (bin.read(bs) != -1) {
                out.write(bs);
            }
        } catch (Exception e) {
            // TODO: handle exception
        } finally {
            bin.close();
            out.flush();
            out.close();
        }
    }

IO流用递归实现查找系统盘里面的所有文件

package com.gaoji.io;

import java.io.File;

public class IOdomemy_01 {
   public static void main(String[] args) {
    //File f = new File("D://");
    File f = new File("D:\\");
    //getFile(f);
}
    //用递归实现查找系统盘里面的所有文件
    public static void getFile(File f) {
        File[] fs = f.listFiles();
        if(fs != null && fs.length !=0){
            for(File f1:fs){
                if(f1.isDirectory()){
                    getFile(f1);
                }else{
                    System.out.println(f1.getName());
                }
            }
        }
    }
}

试题巩固

1.在d盘根目录新建一个a.txt的文件,在文件中输入任意内容

package com.gaoji.io;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
//1.在d盘根目录新建一个a.txt的文件,在文件中输入任意内容
public class IOword_01 {
    public static void main(String[] args) {
        dome0111();
    }
    //用createTempFile创建文件
    public static void dome01(){
        File parent=new File("d:"+File.separator); 
        try {
            File file = parent.createTempFile("hjbqq",".txt",parent);
            System.out.println(file);
            //d:\hjbqq1465893390880583617.txt
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    用createNewFile创建文件
    public static void dome011(){
        File f1=new File("d:"+File.separator);
        File f2=new File(f1,"txt.txt");
        try {
            //有txt.txt则不创建,否,则相反
            f2.createNewFile();
            System.out.println("是否存在:"+f2.exists());
            System.out.println(f2);
            //d:\txt.txt
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    //写入字符流
    public static void dome0111(){
        File f1=new File("d:"+File.separator);
        File f2=new File(f1,"txt.txt");
        try {
            FileWriter fw = new FileWriter(f2);
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write("啊啊啊啊");
            bw.flush();//清除缓冲区
            
            bw.close();
            fw.close();
            System.out.println("写入完毕");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }
}

2.读取txt.txt文件大小,最近访问时间,是否是一个目录。并删除此文件

package com.gaoji.io;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

//读取txt.txt文件大小,最近访问时间,是否是一个目录。并删除此文件
public class IOword_02 {
    public static void main(String[] args) {
        dome1();
    }

    public static void dome1() {
        File f1 = new File("D:"+File.separator);
        File f2 = new File(f1,"txt.txt");
        
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        
        System.out.println(f2);
        System.out.println(f2+"的文件大小是"+f2.length());
        System.out.println(f2+"最后一次被修改的时间是"+sdf.format(new Date(f2.lastModified())));
        System.out.println(f2+"是否是一个目录:"+f2.isDirectory());
        if(f2.delete()){
            System.out.println("删除成功!!");
        }else{
            System.out.println("删除失败");
        }
    }
}

3.编写一个程序,删除这个文件夹中的所有文件(用递归算法来实现)

package com.gaoji.io;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class IOword_03 {

    //创建一个多层的文件夹,每个文件中有不同数目的文件,
    //编写一个程序,删除这个文件夹中的所有文件(用递归算法来实现)
    public static void main(String[] args) throws IOException {
        File f1=new File("d:"+File.separator);
        File f2 = new File(f1,"txt");
        
        getFile(f2);

    }
    //删除指定目录下的文件
    public static void getFile(File f) {
        File[] fs = f.listFiles();
        if(fs != null && fs.length !=0){
            for(File f1:fs){
                if(f1.isDirectory()){
                    getFile(f1);
                }else{
                   f1.delete();
                }
            }
        }
    }
}

资源下载

你可能感兴趣的:(Java)