• 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());
        }
    }

  • 相关阅读:
    $digest / $apply digest in progress报错
    get与post请求
    面试题(北京)
    Docker监控平台prometheus和grafana,监控redis,mysql,docker,服务器信息
    Zabbix系列优秀博文
    Docker安装Zabbix
    使用Docker部署监控系统,Prometheus,Grafana,监控服务器信息及Mysql
    docker镜像加速,docker更换为国内镜像
    记一次,Docker镜像1G多精简至300+M的过程
    docker通过dockerfile构建JDK最小镜像,Docker导出导入镜像
  • 原文地址:https://www.cnblogs.com/t96fxi/p/13261359.html
Copyright © 2020-2023  润新知