浅谈基础IO

目录

IO 简介

了解File类

1. File类基本介绍

2. File类常见操作

1. 流的基本概念

2. 输入输出流

3. 字节流

4. 字符流

序列化与反序列化


IO 简介

在冯诺依曼体系结构我见到了各种各样的输入设备(鼠标、键盘、硬盘、网卡等等)和输出设备(音响、屏幕、硬盘、、网卡等等)。其实,IO(Input/Output)其实解决的就是一个输入输出的问题。

          Input:数据从各种输入设备以二进制流输入到内存中
          Output:数据从内存以二进制流输出到各种输出设备

因为有各种不同的输入输出设备,才会出现不同的输入输出流。而且,数据天生的格式都是字节流(二进制流)。通过上面的分析,我们会发现硬盘既是一种输入设备 又是一种输出设备。那么如何通过java提供的API把内存中的数据保存到硬盘中,又如何把硬盘中的数据读入到内存中呢?我们必须要了解到下面的File类。

了解File类

1. File类基本介绍

File类其实就是描述文件源信息(属性)的一组类。那么文件是什么呢?

书上是这么描述的:文件是相关记录或者放在一起的数据的集合。其实文件就是OS对硬盘空间一块一块的抽象。在windows操作中,经常在硬盘上创建的各种.txt, .doc, .exe, .java, .lib, .mp3等等,都可以称之为文件。文件简单的可以理解成,在外设硬盘上面保存数据的一种方式。

文件一共可以由两部分构成:属性(文件大小,文件名,文件类型等)+内容(就是文件里面放的是什么) 。 File文件操作类在 java.io 包之中,用 File 类来对文件进行操作(创建、删除、取得信息等)

2. File类常见操作

1. 获取文件基本信息

    public static void main(String[] args) throws IOException {
        {
            // File 对象的实际文件不存在
            String path = "D:\\文档\\File类练习\\test.txt";
            File file = new File(path);
            System.out.println(file);
        }

        // 传入一个父路径
        {
            String parent = "D:\\文档\\File类练习";
            String path = "test.txt";
            File file = new File(parent, path);
            System.out.println(file);

            // 获取常见的属性
            System.out.println(file.exists()); //文件是否存在
            System.out.println(file.getAbsolutePath()); //返回绝对路径
            System.out.println(file.getName());  //返回文件名
            System.out.println(file.getParent()); //返回父路径
            System.out.println(file.isAbsolute()); //是否为绝对路径
            System.out.println(file.isDirectory()); //是否是目录
            System.out.println(file.isFile()); //是否是文件
            System.out.println(file.isHidden()); //是否是隐藏的
            System.out.println(file.canRead()); //是否可读
            System.out.println(file.canWrite()); //是否可写
            System.out.println(file.canExecute()); //是否可执行
        }
}

2. 文件的创建

           //普通文件的创建
            String parent = "D:\\文档\\File类练习"; //路径
            String fileName = "文件1.txt"; //文件名

            File file = new File(parent, fileName);

3. 文件夹的创建

            // 文件夹的创建过程
            String parent = "D:\\文档\\File类练习"; //父路径
            String filename = "文件夹的创建"; //文件夹名称
            File file = new File(parent, filename);

4. 文件的删除

         file.deleteOnExit(); //请求在虚拟机终止时删除由此抽象路径名表示的文件或目录。 
         boolean delete = file.delete();// 只能删除一个空的文件夹

5. 文件夹文件的操作

获取文件夹下面的文件

            String path = "D:\\文档";
            File dir = new File(path);

            File[] files = dir.listFiles();
            if (files != null) {
                for (File file : files) {
                    System.out.println(file.getName());
                }
            }

1. 流的基本概念

Java中所有数据都是使用流读写的。流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。

2. 输入输出流

输入 就是将数据从各种输入设备(包括文件、键盘等)中读取到内存中。
输出 就是将数据从内存中写入到各种输出设备(比如文件、显示器、磁盘等)。 
例如:键盘就是一个标准的输入设备,而显示器就是一个标准的输出设备, 但是文件既可以作为输入设备,又可以作为输出设备。

3. 字节流

字节流:数据流中最小的数据单元是字节。 InputStream OutputStream
 
文件输入字节流(读):
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("输入文件.txt")) {
            byte[] buf = new byte[8192];
            int len;

            while ((len = is.read(buf)) != -1) {
                // 有效数据是 buf[0, len)
                for (int i = 0; i < len; i++) {
                    // 如果直接按照数字打印出来,就是打印 ASCII
                    // System.out.println(buf[i]);
                    char c = (char)buf[i];
                    System.out.print(c);
                }
            }
        }
    }

文件输出字节流(写):

    public static void main(String[] args) throws IOException {
        try (OutputStream os = new FileOutputStream("输出内容.txt")) {
           
            // Second 一次写一个字节的方式
            //写法1
            os.write('S');
            os.write('e');
            os.write('c');
            os.write('o');
            os.write('n');
            os.write('d');
            os.write('\r');
            os.write('\n');

            
           // 写法2
            byte[] buf = new byte[1024];
            buf[0] = (byte)'T';
            buf[1] = (byte)'h';
            buf[2] = (byte)'i';
            buf[3] = (byte)'r';
            buf[4] = (byte)'d';
            buf[5] = (byte)'\r';
            buf[6] = (byte)'\n';
            os.write(buf, 0, 7);

            //写法3
            String s = "Hello World\r\n";
            byte[] bytes = s.getBytes(); //string内部可以把它转为byte类型数组
            os.write(bytes);

        
            os.flush(); // 保证把所有缓冲的数据全部写入硬盘中
        }
    }
}

4. 字符流

字符流:数据流中最小的数据单元是字节, Java中的字符是Unicode编码,一个字符占用两个字节:Reader、Writer

文件输入字节流(读):

    private static void read() throws IOException {
        try (InputStream is = new FileInputStream("某篇文章.txt")) {
            try (InputStreamReader isReader = new InputStreamReader(is, "UTF-8")) {
                try (Scanner scanner = new Scanner(isReader)) {
                    // 按行读
                    while (scanner.hasNextLine()) {
                        String line = scanner.nextLine();
                    }
                }
            }
        }
    }

文件输出字节流(写):

    private static void write() throws IOException {
        try (OutputStream os = new FileOutputStream("某篇文章.txt")) {
            try (OutputStreamWriter osWriter = new OutputStreamWriter(os, "UTF-8")) {
                try (PrintWriter printWriter = new PrintWriter(osWriter)) {
                    printWriter.println("");
                    printWriter.printf("");
                    printWriter.print("");
                    printWriter.format("");

                    printWriter.flush();
                }
            }
        }
    }

那么字符流和字节流有什么区别呢?

1.  字节流操作的基本单元是字节;字符流操作的基本单元为 Unicode 码元。
2.  字节流在操作的时候本身不会用到缓冲区的,是与文件本身直接操作的;而字符流在操作的时候使
用到缓冲区的。
3. 所有文件的存储都是字节 (byte) 的存储,在磁盘上保留的是字节。
4.  在使用字节流操作中,即使没有关闭资源( close 方法),也能输出;而字符流不使用 close 方法的
话,不会输出任何内容。

序列化与反序列化

1. 什么是序列化

序列化:把对象转换为字节序列的过程称为对象的序列化。

反序列化:把字节序列恢复为对象的过程称为对象的反序列化。
 
其实就是达到信息 持久化保存起来的效果,那么序列化的意思就是把内存里面的这些对象给变成一连串的字节描述的过程。常见的就是变成文件。

2. 序列化使用场景

3. 如何序列化

实现序列化其实有很多方式:Java对象序列化、JSON序列化、XML等等。如果Java对象进行序列化需要实现Serializable接口即可。

用一组例子来说明序列化和反序列化:

package uesFile.com;

import java.io.*;

public class SerializeDemo {
    // 声明实现 Serializable 接口
    // 声明之后,就拥有了可以序列号和反序列化的功能了
    static class Person implements Serializable {
        String name;
        int age;
    }

    //读
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        try (InputStream is = new FileInputStream("名单.binary")) {
            try (ObjectInputStream ois = new ObjectInputStream(is)) {
                Person p = (Person) ois.readObject();
                System.out.println(p.name);
                System.out.println(p.age);
                Person q = (Person) ois.readObject();
                System.out.println(q.name);
                System.out.println(q.age);
            }
        }
    }

    
    //写
    public static void main(String[] args) throws IOException {
        Person p = new Person();
        p.name = "人员1"; p.age = 34;
        Person q = new Person();
        q.name = "人员2"; q.age = 18;

        try (OutputStream os = new FileOutputStream("名单.binary")) {
            try (ObjectOutputStream oos = new ObjectOutputStream(os)) {
                oos.writeObject(p);
                oos.writeObject(q);

                oos.flush();
            }
        }
    }
    
}

就算程序关闭,文件中的内容也不会消失。实现了先写,再进行读的序列化。这就实现了Java对象的实例化。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值