Java I/O

Java I/O

Java的I/O大概可以分成以下几类:

  • 磁盘操作:File
  • 字节操作:InputStream和OutputStream
  • 字符操作:Reader和Writer
  • 对象操作:Serializable,ObjectInputStream,ObjectOutputStream
  • 网络操作:Socket
  • 非阻塞I/O操作:NIO

磁盘操作(File)

File类可以用于表示文件和目录的信息,但是它不表示文件的内容。

简单使用,递归的输出一个目录下所有文件:

/**
 * Created by DK_ing on 2019/3/26.
 */
public class FileTest {
    public static void listAllFiles(File dir) {
        if (dir == null || !dir.exists()) {
            return;
        }
        if (dir.isFile()) {
            System.out.println(dir.getName());
            return;
        }
        for (File file : dir.listFiles()) {
            listAllFiles(file);
        }
    }
}

字节操作(*Stream)

使用字节流操作进行文件复制:

    public static void copyFile(String src, String dist) {
        try {
            inputStream = new FileInputStream(src);
            outputStream = new FileOutputStream(dist);
            byte[] buffer = new byte[20 * 1024];
            while (inputStream.read(buffer, 0, buffer.length) != -1) {
                outputStream.write(buffer);
            }
        } catch (Exception e) {
            throw new RuntimeException("copy something wrong");
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                throw new RuntimeException("Can not close io", e);
            }

        }
    }

//TODO:此处自行脑补InputStream接口的UML

Java I/O使用了装饰器模式实现,以InputStream为例,InputStream是抽象组件,FileInputStream是InputStream的子类,属于具体组件,提供了字节流的输入操作。FilterInputStream是抽象装饰器,装饰器用于装饰组件,为组件提供额外的功能,例如BufferedInputStream为FileInputStream提供缓存的功能。

实例化一个具有缓存功能的字节流对象时,只需要在FileInputStream对象上再套一层BufferedInputStream对象即可。

FileInputStream fileInputStream = new FileInputStream(filePath);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);

DataInputStream装饰器提供了对更多数据类型进行输入的操作,比如int、double等基本类型。

字符操作(*Reader | *Writer)

不管是磁盘还是网络传输,最小的存储单元都是字节,而不是字符。但是在程序中操作的通常是字符形式的数据,因此需要提供对字符进行操作的方法。

  • InputStreamReader实现从字节流解码成字符流;
  • OutputStreamWriter实现从字符流编码成字节流。

逐行输出文本文件的内容:

    public static void readFileContent(String fileName) throws IOException {
        BufferedReader bufferedReader = null;
        try {
            FileReader fileReader = new FileReader(fileName);
            bufferedReader = new BufferedReader(fileReader);
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (bufferedReader != null) {
            bufferedReader.close();
        }
    }

如果编码或者解码过程使用不同的编码方式,那么就会出现乱码。

注:关于序列化问题以及Socket问题,在分布式基础中有讲到这里不作赘述。

 

你可能感兴趣的:(Java基础,Java基础)