Java IO 知识点总结和盘点,看完后直呼很哇塞(2)

简介: Java IO 知识点总结和盘点,看完后直呼很哇塞

二、操作对象划分


小二,你细想一下,IO IO,不就是输入输出(Input/Output)嘛:


Input:将外部的数据读入内存,比如说把文件从硬盘读取到内存,从网络读取数据到内存等等

Output:将内存中的数据写入到外部,比如说把数据从内存写入到文件,把数据从内存输出到网络等等。

所有的程序,在执行的时候,都是在内存上进行的,一旦关机,内存中的数据就没了,那如果想要持久化,就需要把内存中的数据输出到外部,比如说文件。


文件操作算是 IO 中最典型的操作了,也是最频繁的操作。那其实你可以换个角度来思考,比如说按照 IO 的操作对象来思考,IO 就可以分类为:文件、数组、管道、基本数据类型、缓冲、打印、对象序列化/反序列化,以及转换等。


image.png


1)文件


文件流也就是直接操作文件的流,可以细分为字节流(FileInputStream 和 FileOuputStream)和字符流(FileReader 和 FileWriter)。


FileInputStream 的例子:
int b;
FileInputStream fis1 = new FileInputStream("fis.txt");
// 循环读取
while ((b = fis1.read())!=-1) {
    System.out.println((char)b);
}
// 关闭资源
fis1.close();


FileOutputStream 的例子:


FileOutputStream fos = new FileOutputStream("fos.txt");

fos.write("沉默王二".getBytes());

fos.close();


FileReader 的例子:


int b = 0;
FileReader fileReader = new FileReader("read.txt");
// 循环读取
while ((b = fileReader.read())!=-1) {
    // 自动提升类型提升为 int 类型,所以用 char 强转
    System.out.println((char)b);
}
// 关闭流
fileReader.close();


FileWriter 的例子:


FileWriter fileWriter = new FileWriter("fw.txt");

char[] chars = "沉默王二".toCharArray();

fileWriter.write(chars, 0, chars.length);

fileWriter.close();


当掌握了文件的输入输出,其他的自然也就掌握了,都大差不差。


2)数组


通常来说,针对文件的读写操作,使用文件流配合缓冲流就够用了,但为了提升效率,频繁地读写文件并不是太好,那么就出现了数组流,有时候也称为内存流。


ByteArrayInputStream 的例子:
InputStream is =new BufferedInputStream(
        new ByteArrayInputStream(
                "沉默王二".getBytes(StandardCharsets.UTF_8)));
//操作
byte[] flush =new byte[1024];
int len =0;
while(-1!=(len=is.read(flush))){
    System.out.println(new String(flush,0,len));
}
//释放资源
is.close();


ByteArrayOutputStream 的例子:


ByteArrayOutputStream bos =new ByteArrayOutputStream();
byte[] info ="沉默王二".getBytes();
bos.write(info, 0, info.length);
//获取数据
byte[] dest =bos.toByteArray();
//释放资源
bos.close();


3)管道


Java 中的管道和 Unix/Linux 中的管道不同,在 Unix/Linux 中,不同的进程之间可以通过管道来通信,但 Java 中,通信的双方必须在同一个进程中,也就是在同一个 JVM 中,管道为线程之间的通信提供了通信能力。


一个线程通过 PipedOutputStream 写入的数据可以被另外一个线程通过相关联的 PipedInputStream 读取出来。


final PipedOutputStream pipedOutputStream = new PipedOutputStream();
final PipedInputStream pipedInputStream = new PipedInputStream(pipedOutputStream);
Thread thread1 = new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            pipedOutputStream.write("沉默王二".getBytes(StandardCharsets.UTF_8));
            pipedOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
});
Thread thread2 = new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            byte[] flush =new byte[1024];
            int len =0;
            while(-1!=(len=pipedInputStream.read(flush))){
                System.out.println(new String(flush,0,len));
            }
            pipedInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
});
thread1.start();
thread2.start();



4)基本数据类型


基本数据类型输入输出流是一个字节流,该流不仅可以读写字节和字符,还可以读写基本数据类型。


DataInputStream 提供了一系列可以读基本数据类型的方法:


DataInputStream dis = new DataInputStream(new FileInputStream(“das.txt”)) ;
byte b = dis.readByte() ;
short s = dis.readShort() ;
int i = dis.readInt();
long l = dis.readLong() ;
float f = dis.readFloat() ;
double d = dis.readDouble() ;
boolean bb = dis.readBoolean() ;
char ch = dis.readChar() ;


DataOutputStream 提供了一系列可以写基本数据类型的方法:


DataOutputStream das = new DataOutputStream(new FileOutputStream(“das.txt”));

das.writeByte(10);

das.writeShort(100);

das.writeInt(1000);

das.writeLong(10000L);

das.writeFloat(12.34F);

das.writeDouble(12.56);

das.writeBoolean(true);

das.writeChar('A');



5)缓冲


CPU 很快,它比内存快 100 倍,比磁盘快百万倍。那也就意味着,程序和内存交互会很快,和硬盘交互相对就很慢,这样就会导致性能问题。


为了减少程序和硬盘的交互,提升程序的效率,就引入了缓冲流,也就是类名前缀带有 Buffer 的那些,比如说 BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter。



缓冲流在内存中设置了一个缓冲区,只有缓冲区存储了足够多的带操作的数据后,才会和内存或者硬盘进行交互。简单来说,就是一次多读/写点,少读/写几次,这样程序的性能就会提高。


6)打印


恐怕 Java 程序员一生当中最常用的就是打印流了:System.out 其实返回的就是一个 PrintStream 对象,可以用来打印各式各样的对象。


System.out.println("沉默王二是真的二!");

1

PrintStream 最终输出的是字节数据,而 PrintWriter 则是扩展了 Writer 接口,所以它的 print()/println() 方法最终输出的是字符数据。使用上几乎和 PrintStream 一模一样。


StringWriter buffer = new StringWriter();

try (PrintWriter pw = new PrintWriter(buffer)) {

   pw.println("沉默王二");

}

System.out.println(buffer.toString());


7)对象序列化/反序列化


序列化本质上是将一个 Java 对象转成字节数组,然后可以将其保存到文件中,或者通过网络传输到远程。


ByteArrayOutputStream buffer = new ByteArrayOutputStream();

try (ObjectOutputStream output = new ObjectOutputStream(buffer)) {

   output.writeUTF("沉默王二");

}

System.out.println(Arrays.toString(buffer.toByteArray()));


与其对应的,有序列化,就有反序列化,也就是再将字节数组转成 Java 对象的过程。


try (ObjectInputStream input = new ObjectInputStream(new FileInputStream(

       new File("Person.txt")))) {

   String s = input.readUTF();

}


8)转换


InputStreamReader 是从字节流到字符流的桥连接,它使用指定的字符集读取字节并将它们解码为字符。


InputStreamReader isr = new InputStreamReader(

       new FileInputStream("demo.txt"));

char []cha = new char[1024];

int len = isr.read(cha);

System.out.println(new String(cha,0,len));

isr.close();


OutputStreamWriter 将一个字符流的输出对象变为字节流的输出对象,是字符流通向字节流的桥梁。


File f = new File("test.txt") ;

Writer out = new OutputStreamWriter(new FileOutputStream(f)) ; // 字节流变为字符流  

out.write("hello world!!") ;    // 使用字符流输出  

out.close() ;


“小二啊,你看,经过我的梳理,是不是感觉 IO 也没多少东西!针对不同的场景、不同的业务,选择对应的 IO 流就可以了,用法上就是读和写。”老王一口气讲完这些,长长的舒了一口气。


此时此刻的小二,还沉浸在老王的滔滔不绝中。不仅感觉老王的肺活量是真的大,还感慨老王不愧是工作了十多年的“老油条”,一下子就把自己感觉头大的 IO 给梳理得很清晰了。


相关文章
|
3天前
|
Java 程序员 Windows
【Java知识点详解 10】为何要配置环境变量,35岁老年程序员的绝地翻身之路
【Java知识点详解 10】为何要配置环境变量,35岁老年程序员的绝地翻身之路
|
3天前
|
Java 程序员
Java this关键字详解(3种用法),Java程序员面试必备的知识点
Java this关键字详解(3种用法),Java程序员面试必备的知识点
|
3天前
|
Java 数据库连接 数据安全/隐私保护
springBoot集成token认证,最全Java面试知识点梳理
springBoot集成token认证,最全Java面试知识点梳理
|
5天前
|
监控 Java
Java一分钟之-NIO:非阻塞IO操作
【5月更文挑战第14天】Java的NIO(New IO)解决了传统BIO在高并发下的低效问题,通过非阻塞方式提高性能。NIO涉及复杂的选择器和缓冲区管理,易出现线程、内存和中断处理的误区。要避免这些问题,可以使用如Netty的NIO库,谨慎设计并发策略,并建立标准异常处理。示例展示了简单NIO服务器,接收连接并发送欢迎消息。理解NIO工作原理和最佳实践,有助于构建高效网络应用。
8 2
|
5天前
|
Java 开发者
Java一分钟之-Java IO流:文件读写基础
【5月更文挑战第10天】本文介绍了Java IO流在文件读写中的应用,包括`FileInputStream`和`FileOutputStream`用于字节流操作,`BufferedReader`和`PrintWriter`用于字符流。通过代码示例展示了如何读取和写入文件,强调了常见问题如未关闭流、文件路径、编码、权限和异常处理,并提供了追加写入与读取的示例。理解这些基础知识和注意事项能帮助开发者编写更可靠的程序。
18 0
|
5天前
|
存储 缓存 Java
Java IO 流详解
Java IO 流详解
18 1
|
5天前
|
存储 Java
Java的`java.io`包包含多种输入输出类
【5月更文挑战第2天】Java的`java.io`包包含多种输入输出类。此示例展示如何使用`FileInputStream`从`input.txt`读取数据。首先创建`FileInputStream`对象,接着分配一个`byte`数组存储流中的数据。通过`read()`方法读取数据,然后将字节数组转换为字符串打印。最后关闭输入流释放资源。`InputStream`是抽象类,此处使用其子类`FileInputStream`。其他子类如`ByteArrayInputStream`、`ObjectInputStream`和`BufferedInputStream`各有特定用途。
48 1
|
3天前
|
Java 测试技术
Java多线程的一些基本例子
【5月更文挑战第17天】Java多线程允许并发执行任务。示例1展示创建并启动两个`MyThread`对象,各自独立打印"Hello World"。示例2的`CounterExample`中,两个线程(IncrementThread和DecrementThread)同步地增加和减少共享计数器,确保最终计数为零。这些例子展示了Java线程的基本用法,包括线程同步,还有如Executor框架和线程池等更复杂的用例。
10 0
|
3天前
|
缓存 安全 Java
7张图带你轻松理解Java 线程安全,java缓存机制面试
7张图带你轻松理解Java 线程安全,java缓存机制面试
|
1天前
|
Java
Java一分钟之-并发编程:线程间通信(Phaser, CyclicBarrier, Semaphore)
【5月更文挑战第19天】Java并发编程中,Phaser、CyclicBarrier和Semaphore是三种强大的同步工具。Phaser用于阶段性任务协调,支持动态注册;CyclicBarrier允许线程同步执行,适合循环任务;Semaphore控制资源访问线程数,常用于限流和资源池管理。了解其使用场景、常见问题及避免策略,结合代码示例,能有效提升并发程序效率。注意异常处理和资源管理,以防止并发问题。
20 2
http://www.vxiaotou.com