Java IO

IO

应用程序与外部设备(磁盘和网络)进行数据传输,这些类都被放在java.io中

一。File

File类是io包中唯一代表磁盘文件本身的类,定义了一些与平台无关的方法来操作文件,包括新建,修改,删除,判断是否存在,是否有读写权限,查询和设置最近修改时间等。

RandomAccessFile

支持随机访问文件,可以跳到文件的任意位置。类中有个位置指示器,指向下一个要操作的字节,刚打开时指向文件开头,可以修改该位置进行随机读写。

/**
 * RandomAccessFile可以跳到文件任意位置开始读取
 * skipBytes, seek
 */
public class RandomAccessFileTest {
    public static void main(String[] args) {
        try {
            //write();
            read();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void write() throws IOException {
        Emp emp1 = new Emp("zhangsan",23);
        Emp emp2 = new Emp("lisi",25);
        Emp emp3 = new Emp("wangwu",28);

        RandomAccessFile randomAccessFile = new RandomAccessFile("E:/emp.txt","rw");
        randomAccessFile.writeBytes(emp1.getName());
        randomAccessFile.writeInt(emp1.getAge());
        randomAccessFile.writeBytes(emp2.getName());
        randomAccessFile.writeInt(emp2.getAge());
        randomAccessFile.writeBytes(emp3.getName());
        randomAccessFile.writeInt(emp3.getAge());
        randomAccessFile.close();

    }

    public static void read() throws IOException {
        RandomAccessFile raf = new RandomAccessFile("E:/emp.txt", "rw");
        raf.skipBytes(12); // 跳过第一个员工
        System.out.println("第二个员工");
        String str = "";
        for(int i=0; i<Emp.LEN; i++){
            str += (char)raf.readByte();
        }
        System.out.println("姓名:"+str);
        System.out.println("年龄:"+raf.readInt());
        raf.seek(0);  // 返回文件头部
        System.out.println("第一个员工");
        str = "";
        for(int i=0; i<Emp.LEN; i++){
            str += (char)raf.readByte();
        }
        System.out.println("姓名:"+str);
        System.out.println("年龄:"+raf.readInt());
        raf.skipBytes(12); // 跳过第二个员工
        System.out.println("第三个员工");
        str = "";
        for(int i=0; i<Emp.LEN; i++){
            str += (char)raf.readByte();
        }
        System.out.println("姓名:"+str);
        System.out.println("年龄:"+raf.readInt());
        raf.close();
    }
}

运行结果:

第二个员工
姓名:lisi
年龄:25
第一个员工
姓名:zhangsan
年龄:23
第三个员工
姓名:wangwu 2020-07-072020-07-07
年龄:28

二.流类

JAVA的输入输出流是建立在4个抽象类的基础上: InputStream, OutputStream, Reader,Writer。InputStream, outputStream是为字节流服务,Reader和Writer是为字符流服务。

一般处理字符或字符串用字符流,处理字节或者二进制对象使用字节流。

1。OutputStream(字节输出流)

抽象类, 提供了 write(byte[]) 方法

FileoutputStream(文件字节输出流)

最常见的字节输出流,可以向文件写入字节的类。构造方法FileoutputStream(String fileName), FileoutputStream(File file)

InputStream(字节输入流)

抽象类, 提供了int read(), int read(byte[]) 方法,返回读取的长度如果到末尾-1

FileInputStream(文件字节输入流)

最常见的字节输入流,可以读取文件中字节。构造方法FileInputStream(String fileName), FileInputStream(File file)

public class FileInputStreamTest {
    public static void main(String[] args) {
        try {
            //write();
            read();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void write() throws IOException {
        File file = new File("E:/stream.txt");
        // append=true末尾追加,否则覆盖
        OutputStream out = new FileOutputStream(file, true);
        byte[] b0 = "abcddddd".getBytes();
        out.write(b0);
        out.close();
    }

    public static void read() throws IOException {
        File file = new File("E:/stream.txt");
        InputStream in = new FileInputStream(file);
        byte[] b0 = new byte[(int) file.length()];
        int count = in.read(b0);
        System.out.println(count);
        System.out.println(new String(b0));
    }
}

 2.字符流

字节流处理任何数据类型的输入输出操作(因为计算机上都是0,1存储),但是字节流不能处理unicode字符(万国码)。因为一个unicode字符占两个字节,所以需要字符流

字符流顶层是Reader,Writer

Reader

是字符输入流的抽象类,定义了 int read(), int read(char[])

Write

是字符输出流的抽象类,定义了 write(int) write(char[]), write(String)

FileReader, FileWriter

定义了可以读写文件的字符流, 构造方法 FileReader(String fileName)  FileReader(File file)

/**
 * Reader, Writer是字符流操作字符char,string
 * 一般对于文本的处理基本都用的是字符流,因为字符流有对输入字节进行编解码的功能,
 * 对于其他视频、音频文件一般都使用字节流。
 * 字符流本身就是特殊的字节流
 * inputstream->inputStreamReader->FileReader(字符流是通过字节流包装的)
 * outputstream->outputStreamWriter->FileWriter(字符流是通过字节流包装的)
 */
public class FileReaderTest {
    public static void main(String[] args) {
        try {
            // 1.写文件
            FileWriter out = new FileWriter("E:/writer.txt");
            // 对应的ASCII码字符
            out.write(97);
            out.write("你好");
            out.close();

            // 2.读文件
            FileReader in = new FileReader("E:/writer.txt");
            // 开辟空间接受文件的读取数据
            char[] chars = new char[1024];
            // 返回读入数据的个数
            int count = in.read(chars);
            in.close();
            if(count == -1){
                System.out.println("no data");
            } else {
                System.out.println(new String(chars, 0, count));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

BufferedWriter、BufferedReader

 为了加快字符的读写,引入缓冲机制,一般不直接使用FileReader和FileWriter

构造方法:BufferedWriter(Writer out)  BufferedReader(Reader reader) 

//一般不直接使用FileReader和FileWriter进行读写,避免频繁进行字符和字节之间的相互转换
//BufferedReader封装Reader,BufferedWriter封装Writer
// 带缓冲区
public class BufferedReaderTest {
    public static void main(String[] args) {
        //使用BufferedWriter包装OutputStreamWriter
        // 使用BufferedReader包装InputStreamReader
        try {
            Writer writer = new FileWriter("E:/buffered.txt");
            BufferedWriter bufferedWriter = new BufferedWriter(writer);
            bufferedWriter.write("123
"); // 
换行
            bufferedWriter.write("234
");
            bufferedWriter.write("345
");
            // flush前不会写到文件中
            bufferedWriter.flush();
            bufferedWriter.close();
            writer.close();

            Reader reader = new FileReader("E:/buffered.txt");
            BufferedReader br = new BufferedReader(reader);
            String str = null;
            while((str=br.readLine())!=null){
                System.out.println(str);
            }
            br.close();
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

3管道流

管道流主要用于连接两个线程的通信。管道流也分为字节流(PipedInputStream、PipedOutputStream)和字符流(PipedReader、PipedWriter)

public class PipedInputStreamTest {

    public static void main(String[] args) {
        Sender sender = new Sender();
        Reciever reciever = new Reciever();
        Thread t1 = new Thread(sender);
        Thread t2 = new Thread(reciever);
        PipedOutputStream out = sender.getOutputStream();
        PipedInputStream in = reciever.getInput();
        try {
            out.connect(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
        t1.start();
        t2.start();

    }

    static class Sender implements Runnable{
        private PipedOutputStream out = new PipedOutputStream();

        public PipedOutputStream getOutputStream(){
            return out;
        }
        @Override
        public void run() {
            String str = "你好,管道流";
            try {
                out.write(str.getBytes());
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    static class Reciever implements Runnable{
        private PipedInputStream input = new PipedInputStream();

        public PipedInputStream getInput(){
            return input;
        }
        @Override
        public void run() {
            byte[] b0 = new byte[1024];
            try {
                int length = input.read(b0);
                if(length!=-1){
                    System.out.println(new String(b0, 0,length));
                }
                input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

4.对象流

将对象序列号成二进制字节数组保存在文件进行读写,保存了对象的属性即它的状态

ObjectInputStream、ObjectOutputStream这两个类用于对象序列化操作,构造函数需要传入FileInputStream,FileOutputStream

/**
 * 对象流,对象序列化保存在文件中
 */
public class ObjectInputStreamTest {
    public static void main(String[] args) {
        File file = new File("E:/object.txt");
        try {
            write(file);
            read(file);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

    public static void write(File file) throws IOException {
        OutputStream out = new FileOutputStream(file);
        // ObjectOutputStream是FileOutputStream的装饰类
        ObjectOutputStream oos = new ObjectOutputStream(out);
        Emp emp = new Emp("tom",26);
        oos.writeObject(emp);
        oos.close();
        out.close();
    }

    public static void read(File file) throws IOException, ClassNotFoundException {
        InputStream in = new FileInputStream(file);
        ObjectInputStream ois = new ObjectInputStream(in);
        Emp emp = (Emp)ois.readObject();
        System.out.println(emp.toString());
    }
}

原文地址:https://www.cnblogs.com/t96fxi/p/13261359.html