Java无难事(笔记)-Lesson7-IO

该课内容: Java I/O操作,字节流InputStream和OutputStream,字符流Reader和Writer,Java I/O库的设计原则,字符集的编码,RandomAccessFile类,管道流,对象的序列化.


 

File.

  • 一个File类的对象,表示了磁盘上的文件或目录.
  • File类提供了与平台无关的方法来对磁盘上的文件或目录进行操作.

EX. 文件操作

Java无难事(笔记)-Lesson7-IO
package test;
import java.io.*;
class Test {
    // 由于文件操作很多地方都有异常处理机制.因此做如下简化操作
    public static void main(String[] args) throws Exception{ 
        /*
        File f = new File("123.txt"); // 相对路径
        File f = new File("I:\\Java\\test\\123.txt"); // 绝对路径
        f.createNewFile(); // 创建文件.
        f.mkdir();         // 创建目录
        f.delete();        // 删除文件
        f.deleteOnExit();  // 程序退出时删除文件
        */
        
        // 由于windows下分隔符是/.而linux下是\.此时可用分隔符常量.
        /*
        File fDir = new File(File.separator);
        String strFile = "Java" + File.separator + "test"
                                + File.separator + "123.txt";
        File f = new File(fDir , strFile);
        f.createNewFile();
        */
        
        // 创建临时文件
        for (int i = 0; i < 5; ++i){
            File f = File.createTempFile("test", ".tmp");
            f.deleteOnExit();
        }
        
        // 遍历文件夹下的文件与文件夹
        File fDir = new File(File.separator);
        String strFile = "Java" + File.separator + "test" ;
        File f = new File(fDir, strFile);
        // 实现过滤器接口.对文件名进行过滤
        String[] names = f.list(new FilenameFilter(){
            public boolean accept(File dir, String name){
                return name.indexOf(".txt") != -1;
            }
        });
        for (int i = 0; i < names.length; ++i){
            System.out.println(names[i]);
        }
    }
}
Java无难事(笔记)-Lesson7-IO

流式I/O.

  • 流(Stream)是字节的源或目的.
  • 两种基本的流是.输入流(Input Stream)和输出流(Output Stream).可从中读出一系列字节的对象称为输入流.而能向其中写入一系列字节的对象称为输出流.

流可以分为:

  • 节点流.从特定的地方读写的流类,例如:磁盘或一块内存区域。
  • 过滤流.使用节点流作为输入或输出.过滤流是使用一个已经存在的输入流或输出流连接创建的.

EX. FileInputStream & FileOutputStream

Java无难事(笔记)-Lesson7-IO
package test;
import java.io.*;
class Test {
    public static void main(String[] args) throws Exception{ 
        // FileInputStream\FileOutputStream        
        // 向文件中写入数据
        FileOutputStream fos = new FileOutputStream("123.txt");
        fos.write("come on".getBytes());
        fos.close();
        
        // 从文件中读取数据
        FileInputStream fis = new FileInputStream("123.txt");
        byte[] buf = new byte[100];
        int len = fis.read(buf);
        System.out.println(new String(buf, 0, len));
        fis.close();
    }
}
Java无难事(笔记)-Lesson7-IO

EX. BufferedInputStream & FileOutputStream

Java无难事(笔记)-Lesson7-IO
package test;
import java.io.*;
class Test {
    public static void main(String[] args) throws Exception{     
        // 向文件中写入数据
        FileOutputStream fos = new FileOutputStream("123.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        bos.write("come on".getBytes()); // 将数据写入缓冲区
        bos.flush(); // 将缓冲区写入硬盘
        bos.close(); // 只需要关闭bos即可
        
        // 从文件中读取数据
        FileInputStream fis = new FileInputStream("123.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
        byte[] buf = new byte[100];
        int len = bis.read(buf);
        bis.close();
        System.out.println(new String(buf, 0, len));
        bis.close();
    }
}
Java无难事(笔记)-Lesson7-IO

EX. DataInputStream & DataOutputStream

Java无难事(笔记)-Lesson7-IO
package test;
import java.io.*;
class Test {
    public static void main(String[] args) throws Exception{     
        // 向文件中写入数据
        FileOutputStream fos = new FileOutputStream("123.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        DataOutputStream dos = new DataOutputStream(bos);
        byte b = 3;
        int i = 78;
        char ch = ‘a‘;
        float f = 4.5f;
        dos.writeByte(b);
        dos.writeInt(i);
        dos.writeChar(ch);
        dos.writeFloat(f);
        dos.close();
        
        // 从文件中读取数据
        FileInputStream fis = new FileInputStream("123.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
        DataInputStream dis = new DataInputStream(bis);
        System.out.println(dis.readByte());
        System.out.println(dis.readInt());
        System.out.println(dis.readChar());
        System.out.println(dis.readFloat());
        bis.close();
    }
}
Java无难事(笔记)-Lesson7-IO

EX. PipedInputStream & PipedOutputStream. 线程间通信

Java无难事(笔记)-Lesson7-IO
package test;
import java.io.*;
class Test {
    public static void main(String[] args) throws Exception{     
        PipedOutputStream pos = new PipedOutputStream();
        PipedInputStream pis = new PipedInputStream();
        try {
            pos.connect(pis);
            new Producer(pos).start();
            new Consumer(pis).start();
        }
        catch (Exception ex){
            ex.printStackTrace();
        }
    }
}

class Producer extends Thread{
    private PipedOutputStream pos;
    public Producer(PipedOutputStream pos){
        this.pos = pos;
    }
    public void run(){
        try{
            pos.write("hello world.".getBytes());
            pos.close();
        }
        catch (Exception ex){
            ex.printStackTrace();
        }
        
        
    }
}
class Consumer extends Thread{
    private PipedInputStream pis;
    public Consumer(PipedInputStream pis){
        this.pis = pis;
    }
    public void run(){
        try{
            byte[] buf = new byte[100];
            int len = pis.read(buf);
            System.out.println(new String(buf, 0,len));
            pis.close();
        }
        catch (Exception ex){
            ex.printStackTrace();
        }
    }
}
Java无难事(笔记)-Lesson7-IO

流式I/O的链接.

Java无难事(笔记)-Lesson7-IO


ReaderWriter.

  • Java程序语言使用Unicode来表示字符串和字符.
  • Reader和Writer这两个抽象类主要用来读写字符流.

EX. BufferedWriter & BufferedReader. 线程间通信

Java无难事(笔记)-Lesson7-IO
package test;
import java.io.*;
class Test {
    public static void main(String[] args) throws Exception{     
        // 写入字符流
        FileOutputStream fos = new FileOutputStream("123.txt");
        OutputStreamWriter osw = new OutputStreamWriter(fos);
        BufferedWriter bw = new BufferedWriter(osw);
        bw.write("come on");
        bw.close();
        
        // 读取字符流
        FileInputStream fis = new FileInputStream("123.txt");
        InputStreamReader isr = new InputStreamReader(fis);
        BufferedReader br = new BufferedReader(isr);
        System.out.println(br.readLine());
        br.close();
        
        InputStreamReader isr2 = new InputStreamReader(System.in);
        BufferedReader br2 = new BufferedReader(isr2);
        String strLine;
        while ((strLine = br2.readLine() )!= null){
            System.out.println(strLine);
        }
        br.close();
    }
}
Java无难事(笔记)-Lesson7-IO

字符集的编码.

  • ASCII(American Standard Code for Information Interchange,美国信息互换标准代码),是基于常用的英文字符的一套电脑编码系统。我们知道英文中经常使用的字符、数字符号被计算机处理时都是以二进制码的形式出现的。这种二进制码的集合就是所谓的ASCII码。每一个ASCII码与一个8位(bit)二进制数对应。其最高位是0,相应的十进制数是0-127。如,数字“0”的编码用十进制数表示就是48。另有128个扩展的ASCII码,最高位都是1,由一些制表符和其它符号组成。ASCII是现今最通用的单字节编码系统。
  • GB2312:GB2312码是*国家汉字信息交换用编码,全称《信息交换用汉字编码字符集-基本集》。主要用于给每一个中文字符指定相应的数字,也就是进行编码。一个中文字符用两个字节的数字来表示,为了和ASCII码有所区别,将中文字符每一个字节的最高位置都用1来表示。
  • GBK:为了对更多的字符进行编码,国家又发布了新的编码系统GBK(GBK的K是“扩展”的汉语拼音第一个字母)。在新的编码系统里,除了完全兼容GB2312 外,还对繁体中文、一些不常用的汉字和许多符号进行了编码。
  • ISO-8859-1:是西方国家所使用的字符编码集,是一种单字节的字符集 ,而英文实际上只用了其中数字小于128的部分。
  • Unicode:这是一种通用的字符集,对所有语言的文字进行了统一编码,对每一个字符都用2个字节来表示,对于英文字符采取前面加“0”字节的策略实现等长兼容。如 “a” 的ASCII码为0x61,UNICODE就为0x00,0x61。
  • UTF-8:Eight-bit UCS Transformation Format,(UCS,Universal Character Set,通用字符集,UCS 是所有其他字符集标准的一个超集)。一个7位的ASCII码值,对应的UTF码是一个字节。如果字符是0x0000,或在0x0080与0x007f之间,对应的UTF码是两个字节,如果字符在0x0800与0xffff之间,对应的UTF码是三个字节。

RandomAccessFile.

  • RandomAccessFile类同时实现了DataInput和DataOutput接口,提供了对文件随机存取的功能,利用这个类可以在文件的任何位置读取或写入数据。
  • RandomAccessFile类提供了一个文件指针,用来标志要进行读写操作的下一数据的位置。

EX. RandomAccessFile示例

Java无难事(笔记)-Lesson7-IO
package test;
import java.io.*;
class Test {
    public static void main(String[] args) throws Exception{
        Student s1 = new Student(1, "a", 90);
        Student s2 = new Student(2, "b", 90.5);
        Student s3 = new Student(3, "c", 89.5);
        RandomAccessFile raf = new RandomAccessFile("Student.txt", "rw");
        s1.writeStudent(raf);
        s2.writeStudent(raf);
        s3.writeStudent(raf);
        
        Student s = new Student();
        raf.seek(0); // 将文件指针移至文件起始位置
        for (long i = 0; i < raf.length(); i = raf.getFilePointer()){
            s.readStudent(raf);
            System.out.println(s);
        }
        raf.close();
    }
}
class Student{
    int id;
    String name;
    double score;
    public Student(){}
    public Student(int id, String name, double score){
        this.id = id;
        this.name = name;
        this.score = score;
    }
    // 写入数据
    public void writeStudent(RandomAccessFile raf) throws IOException{
        raf.writeInt(id);
        raf.writeUTF(name);
        raf.writeDouble(score);
    }
    // 读取数据
    public void readStudent(RandomAccessFile raf) throws IOException{
        id = raf.readInt();
        name = raf.readUTF();
        score = raf.readDouble();
    }
    public String toString(){
        return "id:" + id + ", name:" + name + ", score:" + score;
    }
}
Java无难事(笔记)-Lesson7-IO

对象序列化.

  • 将对象转换为字节流保存起来,并在日后还原这个对象,这种机制叫做对象序列化。
  • 将一个对象保存到永久存储设备上称为持续性。
  • 一个对象要想能够实现序列化,必须实现Serializable接口或Externalizable接口。
  • 当一个对象被序列化时,只保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量。
  • 如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存。
  • 如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个NotSerializableException。我们可以将这个引用标记为transient,那么对象仍然可以序列化。

EX.序列化示例

Java无难事(笔记)-Lesson7-IO
package test;
import java.io.*;
class Test {
    public static void main(String[] args) throws Exception{
        Employee e1 = new Employee("a", 23, 3000);
        Employee e2 = new Employee("b", 24, 4000);
        Employee e3 = new Employee("c", 25, 5000);
        
        FileOutputStream fos = new FileOutputStream("employee.txt");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(e1);
        oos.writeObject(e2);
        oos.writeObject(e3);
        oos.close();
        
        // 反序列化.(不调用对象的任何构造方法)
        FileInputStream fis = new FileInputStream("employee.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);
        for (int i = 0; i < 3; ++i)
            System.out.println(ois.readObject());
    }
}

class Employee implements Serializable{
    String name;
    int age;
    double salary;
    public Employee(String name, int age, double salary){
        this.name = name;
        this.age = age;
        this.salary = salary;
    }
    public String toString(){
        return "name:" + name + ", age:" + age + ", salary:" + salary;
    }
    
    /* 自定义序列化
    private void writeObject(ObjectOutputStream oos) throws IOException{}
    private void readObject(ObjectInputStream oos) throws IOException{}
    */
}
Java无难事(笔记)-Lesson7-IO

 

Java无难事(笔记)-Lesson7-IO,布布扣,bubuko.com

Java无难事(笔记)-Lesson7-IO

上一篇:javaSE语言基础问题记录


下一篇:Kubernetes使用vSphere存储 - vSphere-CSI (Rancher创建)