java中的输入与输出(I/O)

news2025/2/27 7:18:44

Java I/O(输入/输出)是Java程序与外部世界进行交互的重要机制,它允许程序读取和写入数据到各种类型的源,如文件、网络套接字、管道、内存缓冲区等。Java I/O API主要位于java.io包中,提供了丰富的类和接口来处理不同类型的输入输出操作。以下是Java I/O的一些关键知识点总结:

1. File类

  • java.io.File类代表一个文件或目录的路径名抽象表示,与平台无关。
  • 可以用来创建、删除文件或目录,检查文件是否存在,获取文件大小,列出目录内容等。

在Java中,File类是java.io包中的一个关键类,它用来表示文件和目录的路径名,提供了许多与平台无关的方法来操作文件和目录。以下是对File类的一些重要特性和方法的总结:

特性:
  • 平台无关性File类允许以一种与平台无关的方式操作文件和目录,使得Java程序可以在不同的操作系统上运行而无需修改文件操作的代码。
  • 不涉及内容操作File类主要处理文件和目录的元数据操作,如创建、删除、重命名文件或目录,检查文件是否存在、是否可读写等,但不直接涉及文件内容的读写,内容操作需要配合输入输出流(如FileInputStreamFileOutputStream等)完成。
常用构造方法:
  • File(String pathname):通过路径名字符串创建File对象。
  • File(String parent, String child):根据父目录路径名字符串和子路径名字符串创建File对象。
  • File(File parent, String child):根据父File对象和子路径名字符串创建File对象。
常用方法:
  • 判断与查询

    • exists():测试此File表示的文件或目录是否存在。
    • isDirectory():测试此File是否为目录。
    • isFile():测试此File是否为文件。
    • length():返回由此File表示的文件的长度。
    • list():返回此File表示的目录中的文件和目录名列表。
  • 创建与删除

    • createNewFile():当此File表示的文件不存在时,创建一个新的空文件。
    • mkdir():创建由此File表示的单级目录。
    • mkdirs():创建由此File表示的多级目录。
    • delete():删除由此File表示的文件或目录。
  • 重命名与移动

    • renameTo(File dest):重命名此File表示的文件或目录。
  • 获取路径与信息

    • getAbsolutePath():返回此File的绝对路径名字符串。
    • getPath():返回此File的路径名字符串。
    • getParent():返回此File的父路径名字符串,如果没有则返回null。
  • 其他操作

    • canRead()canWrite()setReadable(boolean readable)setWritable(boolean writable)等用于权限控制的方法。

注意,尽管File类提供了丰富的文件系统操作,但在处理文件I/O操作时,通常需要结合InputStream、OutputStream、Reader、Writer等类来读写文件内容。此外,对于更高级的文件和I/O操作,如内存映射文件、非阻塞I/O等,Java NIO(New I/O)包提供了更为强大的功能。

2. 流的概念

  • Java I/O是基于流模型的,流是连续的数据序列。
  • 流分为输入流(读取数据)和输出流(写入数据)。
  • 流可以是字节流或字符流,分别处理字节数据和字符数据。

在计算机编程中,"流"(Stream)是一个非常核心的概念,它是一种抽象的表示数据传输的方式。流可以看作是数据在两个实体(如程序和文件、内存和网络、或者程序的不同部分之间)之间的连续传输。这个概念强调的是数据的流动性和处理过程,而不是数据本身或者容器。

基本特性:
  1. 方向性:流分为输入流(Input Stream)和输出流(Output Stream)。输入流用于从源(如文件、网络、键盘)读取数据到程序中;输出流则负责将数据从程序输出到目标(如文件、网络、屏幕)。

  2. 有序性:流中的数据是有序的,数据元素按照一定的顺序被处理,这个顺序通常反映了数据在源中的排列或传输的时序。

  3. 动态性:流在处理过程中,数据可以一边被读取或写入一边被处理,不需要等待所有数据都加载完毕才开始操作,这对于处理大量数据或网络传输尤为重要。

  4. 类型:流可以是字节流或字符流。字节流(如InputStreamOutputStream)以字节(Byte)为基本单位处理数据,适用于任何类型的数据,包括二进制数据。字符流(如ReaderWriter)以字符(Character)为基本单位,通常用于处理文本数据。

  5. 装饰器模式:Java I/O体系中广泛使用装饰器模式,允许通过添加额外的类(装饰者)来扩展基本流的功能,比如增加缓冲(BufferedInputStream)、数据压缩、加密等功能,而不需要改变原有流的接口。

  6. 资源管理:使用流时需要考虑资源的释放,尤其是在异常情况下,Java 7引入的try-with-resources语句可以自动关闭流,以防止资源泄露。

应用场景:
  • 文件操作:读写文件内容。
  • 网络通信:发送和接收网络数据包。
  • 内存数据交换:在程序的不同部分之间传递数据。
  • 标准输入输出:与控制台或系统标准输入输出设备交互。

总的来说,流为开发者提供了一种灵活而统一的方式来处理各种数据传输任务,无论数据来源或目的地如何变化,都可以通过相同的编程模型来处理。

3. 字节流与字符流

  • 字节流:操作的基本单位是字节(8位),主要用于文件、网络等原始数据的读写。

    • InputStream(字节输入流):如FileInputStreamByteArrayInputStream
    • OutputStream(字节输出流):如FileOutputStreamByteArrayOutputStream
  • 字符流:操作的基本单位是字符(使用Unicode编码,通常是16位),主要用于文本数据的读写。

    • Reader(字符输入流):如FileReaderCharArrayReader
    • Writer(字符输出流):如FileWriterCharArrayWriter

在Java的I/O操作中,字节流和字符流是最基础也是最重要的两个概念,它们分别对应于不同的数据处理需求和场景。

字节流(Byte Streams)

字节流以字节(byte)为基本单位进行数据的读写操作,主要用于处理二进制数据,如图片、音频、视频文件或原始数据传输。字节流是Java I/O中最基本的形式,所有的InputStream和OutputStream子类都是字节流的实现。

主要类:
  • InputStream:所有字节输入流的基类,如FileInputStream(从文件读取字节)、ByteArrayInputStream(从字节数组读取)。
  • OutputStream:所有字节输出流的基类,如FileOutputStream(向文件写入字节)、ByteArrayOutputStream(写入字节数组)。
字符流(Character Streams)

字符流以字符(char)为基本单位进行数据的读写操作,特别适合处理文本数据。字符流内部会使用字节流来读写数据,同时加上了字符编码和解码的处理,使得开发者可以以字符的形式直接操作文本,而不需要关心底层的字节编码细节。

主要类:
  • Reader:所有字符输入流的基类,如FileReader(从文件读取字符)、CharArrayReader(从字符数组读取)。
  • Writer:所有字符输出流的基类,如FileWriter(向文件写入字符)、CharArrayWriter(写入字符数组)。
区别与联系:
  1. 数据处理单位:最根本的区别在于处理数据的基本单位,字节流处理字节,字符流处理字符(通常一个字符由多个字节组成,具体取决于字符编码)。
  2. 编码转换:字符流内部实现了字节到字符的转换,即自动进行字符编码和解码,更适合处理文本文件。而字节流则直接操作字节,适用于所有类型的数据传输。
  3. 性能:对于文本数据,字符流由于包含了编码转换过程,理论上性能略低于直接操作字节的字节流。但在实际应用中,这种差异往往可以忽略,特别是当使用缓冲流(如BufferedReaderBufferedWriter)时,性能差异更小。
  4. 互操作性:字节流和字符流可以通过转换流(如InputStreamReaderOutputStreamWriter)相互转换,从而在需要时灵活切换处理方式。

总之,选择字节流还是字符流主要取决于数据的类型和处理需求。处理文本文件或文本数据时推荐使用字符流,因为它更加方便且易于理解;而对于非文本的二进制数据,则应使用字节流。

4. 装饰器模式

  • Java I/O使用装饰器模式(Decorator Pattern)增强基本流的功能,如缓冲(BufferedInputStreamBufferedReader)、数据转换(DataInputStreamPrintWriter)、线程安全(PipedInputStreamPipedOutputStream)等。

装饰器模式(Decorator Pattern)是一种结构型设计模式,它动态地给一个对象添加一些额外的职责(行为或责任),就增加功能来说,装饰器模式相比生成子类更为灵活。这种模式创建了一个装饰类,用来包装原有的类,并在保持原有类方法签名完整性的基础上,提供了额外的功能。

在Java I/O编程中,装饰器模式被广泛应用来增强基本的输入输出流的功能,而不需要修改这些流的原始类。装饰器模式的关键在于它遵循了“开闭原则”,即对扩展开放(可以容易地添加新的功能),对修改封闭(不需要修改现有的代码)。

Java I/O中的装饰器模式示例

假设我们有一个基本的字节输入流InputStream,现在想要添加缓冲功能以提高读取效率,同时不影响原有InputStream的接口和使用方式。这时,我们可以创建一个装饰类BufferedInputStream,它内部持有一个InputStream引用,并扩展了读取方法以实现缓冲逻辑。

public class BufferedInputStream extends FilterInputStream {
    // ...
    public BufferedInputStream(InputStream in) {
        super(in);
        // 初始化缓冲区等操作
    }
    
    public int read() throws IOException {
        // 实现缓冲读取逻辑,可能调用super.read(),并利用缓冲提高效率
    }
    
    // 可能还有read(byte[] b), skip(long n)等方法的重写,以提供缓冲功能
    // ...
}

在这个例子中,BufferedInputStream就是装饰器类,它继承自FilterInputStream(过滤输入流,一个抽象装饰类),并接受一个InputStream实例作为参数。这样,任何实现了InputStream接口的类都可以通过BufferedInputStream来增加缓冲功能,而无需修改原始类的代码。

装饰器模式的优点:
  1. 灵活性:可以在运行时动态地添加或移除装饰器,以改变对象的行为。
  2. 重用性:装饰器类可以单独使用,也可以组合使用,以构建复杂的功能。
  3. 遵循开闭原则:允许在不修改现有类的基础上扩展功能。
在Java I/O中的其他应用:

除了BufferedInputStreamBufferedOutputStream外,Java I/O还提供了许多其他装饰器类,如DataInputStreamDataOutputStream用于处理基本数据类型,PrintWriter用于格式化文本输出等,这些都是装饰器模式的具体应用实例,大大增强了Java I/O的灵活性和功能性。

5. 缓冲流

  • 缓冲流(BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter)通过在内存中缓存数据来减少实际I/O操作次数,提高效率。

缓冲流,全称为缓冲区输入/输出流(Buffered InputStream/OutputStream/Reader/Writer),是Java I/O库中提供的一种提高读写效率的流。它们通过在物理流(如FileInputStream/FileOutputStream)和程序之间增加一个缓冲区来工作,从而减少实际的磁盘访问次数,提高数据处理速度。

缓冲输入流
  • BufferedInputStream 和 BufferedReader 是两种基本的缓冲输入流。
  • BufferedInputStream 用于字节流,它从底层的输入流中读取数据到缓冲区中,当缓冲区满或者调用read()方法时,才真正从缓冲区中读取数据。
  • BufferedReader 用于字符流,除了缓冲功能外,还提供了方便的行读取功能(如readLine()方法),这对于文本文件的读取特别有用。

缓冲输出流

  • BufferedOutputStream 和 BufferedWriter 是两种基本的缓冲输出流。
  • BufferedOutputStream 用于字节流,它不是立即把数据写入到目的地,而是先将数据写入缓冲区,当缓冲区满或者调用flush()方法时,再一次性将缓冲区中的数据写出到目的地。
  • BufferedWriter 用于字符流,同样利用缓冲技术提高输出效率,并提供了如newLine()等便捷方法处理文本输出格式。

优点

  1. 提高效率:减少了实际的I/O操作次数,因为每次读写都是针对内存中的缓冲区,而非直接的物理磁盘操作。
  2. 功能增强:如BufferedReader提供了按行读取的功能,而缓冲输出流可以更高效地处理大块数据的写入。

使用示例

字节缓冲流示例
import java.io.*;

public class BufferedStreamDemo {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("source.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
        
        FileOutputStream fos = new FileOutputStream("destination.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        
        int data;
        while((data = bis.read()) != -1){
            bos.write(data);
        }
        
        bis.close();
        bos.close();
    }
}
字符缓冲流示例
import java.io.*;

public class BufferedReaderDemo {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("textfile.txt");
        BufferedReader br = new BufferedReader(fr);
        
        FileWriter fw = new FileWriter("copiedText.txt");
        BufferedWriter bw = new BufferedWriter(fw);
        
        String line;
        while((line = br.readLine()) != null){
            bw.write(line);
            bw.newLine(); // 写入新行
        }
        
        br.close();
        bw.close();
    }
}

使用缓冲流可以显著提升文件读写操作的性能,尤其是在处理大量数据时。

6. 标准输入/输出流

  • System.inSystem.out, 和 System.err 分别代表标准输入、标准输出和标准错误流。

标准输入/输出流是程序与用户进行交互的基本方式,允许程序接收用户的输入并输出结果到用户界面,通常是终端或控制台。在大多数编程语言中,标准输入/输出流被预定义并可以直接使用。以下是一些关于标准输入/输出流的基础概念和常见用法:

标准输入(stdin)
  • 概念:标准输入流是指程序从外部接收数据的通道,最常见的情况是从键盘接收用户的输入。在Java中,标准输入流由 System.in 表示,它是一个 InputStream 类型的对象。
  • 使用场景:当你需要让程序等待并根据用户的输入来决定下一步动作时,就会用到标准输入流。
标准输出(stdout)
  • 概念:标准输出流是程序用来输出数据到用户界面的通道,最常见的输出设备是显示器或控制台。在Java中,标准输出流由 System.out 表示,它是一个 PrintStream 类型的对象,支持格式化输出。
  • 使用场景:几乎所有的程序都会用到标准输出来展示处理结果、提示信息或错误信息。
标准错误输出(stderr)
  • 虽然你没有直接问及,但标准错误输出也是一个重要的概念,通常用于输出程序运行时的错误信息。在Java中,它由 System.err 表示,也是一个 PrintStream 类型的对象。标准错误输出与标准输出是分开的,这样设计允许程序将错误信息和正常输出分开管理,便于调试和日志记录。
示例代码(Java)
读取标准输入
import java.util.Scanner;

public class StdInputExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in); // 创建Scanner对象以读取标准输入
        System.out.println("请输入一些文本:");
        String userInput = scanner.nextLine(); // 读取一行输入
        System.out.println("你输入的是:" + userInput);
        scanner.close();
    }
}
输出到标准输出
public class StdOutputExample {
    public static void main(String[] args) {
        System.out.println("这是一个标准输出的例子。");
        System.out.printf("当前时间是:%tc%n", System.currentTimeMillis()); // 格式化输出当前时间
    }
}

通过理解和使用标准输入/输出流,开发者能够创建与用户互动的程序,无论是简单的命令行工具还是复杂的图形界面应用,这些基本的输入输出机制都是基础且必要的。

7. 对象序列化与反序列化

  • 使用ObjectOutputStreamObjectInputStream可以将对象写入流中(序列化)和从流中读取对象(反序列化)。

对象序列化与反序列化是面向对象编程中用于处理对象状态转换的重要概念,主要用于对象的持久化存储和网络传输。以下是这两个概念的详细解释:

对象序列化

序列化是指将一个对象的状态(即成员变量的值)转换为一个可以存储或传输的格式(如字节数组或其他格式)的过程。这一过程涉及到将对象的公共和私有字段转换成一种格式,这种格式可以被保存到文件、数据库、或通过网络发送到另一台计算机上。在Java中,要使一个对象可被序列化,该对象的类必须实现 Serializable 接口(即使该接口没有方法)。序列化可以通过 ObjectOutputStream 类的 writeObject() 方法来完成。

反序列化

反序列化则是序列化过程的逆过程,即将已经序列化后的数据(如字节数组)恢复成原来的对象状态。这个过程涉及根据存储的数据重新构造对象,包括重新分配内存并恢复对象的字段值。在Java中,反序列化是通过 ObjectInputStream 类的 readObject() 方法实现的。

应用场景
  1. 对象持久化:将对象状态保存到磁盘上,以便在未来某个时刻能恢复对象。
  2. 网络通信:在分布式系统中,对象需要通过网络在不同节点间传递,序列化和反序列化使得对象能够以字节流的形式在网络上进行传输。
  3. 进程间通信:在同一台机器的不同进程中传递对象,也需要序列化和反序列化。
  4. 缓存:将对象存储在内存缓存中,如Redis,以便快速检索。
注意事项
  • 并非所有对象都可以被序列化,比如当对象引用了不可序列化的对象时,会抛出 NotSerializableException 异常。
  • 在序列化和反序列化过程中,对象的类定义必须保持一致,否则可能会出现 ClassNotFoundException 或是数据不一致的问题。
  • Java提供了 Externalizable 接口,它继承自 Serializable,允许开发者自定义序列化和反序列化过程,以优化性能或处理特殊需求。
  • 安全性考虑:反序列化有时会被用作攻击向量,恶意构造的序列化数据可能导致安全漏洞,因此需要谨慎处理。

总的来说,序列化和反序列化是实现数据交换和持久化的重要技术,但在使用时需注意安全性和兼容性问题。

8. NIO (New I/O)

  • Java 1.4引入了NIO(非阻塞I/O),提供更高效的数据处理方式,特别是对于高并发的网络应用。NIO使用通道(Channel)和缓冲区(Buffer)模型。

NIO,全称 New I/O 或 Non-blocking I/O,是Java 1.4版本引入的一个新的IO API,旨在提供更高效、更灵活的IO操作,特别是对于高并发、大吞吐量的网络应用。NIO的核心在于非阻塞式操作、缓冲区(Buffer)和通道(Channel)的概念。

非阻塞式操作

与传统的Java I/O(也称为BIO,Blocking I/O)相比,NIO的一个重要特性是非阻塞式操作。在BIO中,当一个线程执行读或写操作时,如果数据没有准备好(例如,网络数据未到达或缓冲区已满),该线程会被阻塞,直到操作完成。这导致线程资源被大量占用,特别是在处理大量并发连接时。

而在NIO中,非阻塞模式允许线程在数据未准备好时立即返回,无需等待,从而可以继续执行其他任务。当数据准备好后,再通过事件通知或轮询的方式进行处理,大大提高了系统的并发处理能力。

缓冲区(Buffer)

NIO的所有数据都是通过缓冲区处理的。缓冲区实质上是一个数组,它可以保存不同数据类型的数据,如字节(ByteBuffer)、字符(CharBuffer)等。缓冲区的主要优点是减少实际的物理读写操作次数,提高效率。数据读取到缓冲区或从缓冲区写入通道都是通过缓冲区进行的。

通道(Channel)

通道是NIO中另一个核心组件,它是连接到实体(如文件、套接字)的双向数据传输管道。与流(Stream)不同,通道可以同时进行读写操作。NIO中的关键通道类包括FileChannel(用于文件操作)、SocketChannel(客户端套接字通道)和ServerSocketChannel(服务器端套接字通道)。

选择器(Selector)

选择器是NIO中用于实现多路复用的关键组件,它允许单个线程管理多个通道。通过注册通道到选择器上,并指定关注的事件(如读就绪、写就绪等),线程可以监听多个通道上的事件,从而实现高度并发的服务。当某个通道上有事件发生时,选择器会通知应用程序,应用程序再针对性地处理相应的通道事件,极大地提高了处理效率。

总结

NIO通过非阻塞I/O、缓冲区、通道和选择器等机制,为Java开发者提供了构建高性能网络应用和服务的新工具。它特别适合于需要处理大量并发连接和高吞吐量的场景,如Web服务器、即时通讯系统等。不过,NIO的编程模型相对复杂,对开发者的要求较高。在Java 7之后,随着异步I/O(AIO)的引入,进一步丰富了Java的I/O处理能力,为开发者提供了更多选择。

9. 文件锁定与随机访问

  • FileChannel支持文件的锁定和解锁操作,以及随机访问文件内容。

在Java中,文件锁定和随机访问是两个不同的概念,但它们经常在处理文件时一起使用,尤其是当需要在多线程或跨进程环境中安全地进行文件读写操作时。

文件锁定(File Locking)

文件锁定是Java NIO(New I/O)库提供的一种机制,用于控制对文件的并发访问,确保数据的一致性和完整性。通过FileChannel类的lock()tryLock()方法,可以对文件的部分或全部进行加锁。文件锁是劝告式的(advisory),意味着它们并不强制操作系统层面的锁定,而是依赖于参与的程序遵守锁规则。

  • 共享锁:允许多个线程或进程同时读取文件,但任何时刻只能有一个进程或线程对其进行写入。
  • 独占锁:只允许一个线程或进程访问文件,无论是读取还是写入。其他尝试访问该文件的线程或进程将会被阻塞,直到锁被释放。
随机访问(Random Access)

随机访问文件是指能够直接定位到文件的任意位置进行读写操作的能力,而不是像顺序访问那样从头到尾依次读写。Java NIO中的FileChannel以及SeekableByteChannel接口(FileChannel实现了这个接口)支持随机访问文件。

  • SeekableByteChannel:提供position(long)方法来设置读写位置,以及read(ByteBuffer)write(ByteBuffer)等方法在当前位置进行数据读写,允许程序灵活地跳转到文件的任意位置进行操作。
  • MappedByteBuffer:虽然不是直接的随机访问接口,但是通过内存映射文件的方式,可以非常高效地进行大文件的随机访问。通过FileChannel.map(MapMode, long, long)方法,可以将文件的一部分或全部映射到内存中,然后通过直接操作这个内存缓冲区来进行高速的随机读写。

结合使用文件锁定和随机访问,可以在并发环境下安全高效地进行文件的读写操作。例如,在一个多线程应用中,可以先获取文件的锁以确保独占访问,然后使用随机访问功能直接定位并修改文件的特定部分,最后释放锁,允许其他线程或进程进行访问。这样既保证了数据一致性,又充分利用了随机访问带来的效率优势。

10. 资源管理

  • 使用try-with-resources语句自动关闭资源(Java 7起),避免忘记关闭流导致的资源泄露问题。

资源管理在软件开发中是一个至关重要的方面,它涉及有效、安全地分配和释放系统资源,如文件句柄、数据库连接、网络连接、内存等。良好的资源管理可以避免资源泄露、提升系统性能和稳定性。下面是一些关键原则和实践方法,特别是在Java编程中:

自动资源管理 (ARM, Automatic Resource Management)

从Java 7开始,通过try-with-resources语句自动管理资源成为可能。这个特性允许在try语句块中声明资源,并确保这些资源在try块结束时(无论是否发生异常)自动关闭。这对于文件操作、数据库连接等需要显式关闭的资源尤其有用。

try (FileInputStream fis = new FileInputStream("file.txt");
     FileOutputStream fos = new FileOutputStream("copy.txt")) {
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = fis.read(buffer)) != -1) {
        fos.write(buffer, 0, bytesRead);
    }
} // fis和fos在此自动关闭
显式资源关闭

在不支持自动资源管理的场景或旧版Java中,需要手动确保每个打开的资源在不再需要时被正确关闭。通常,这应该在finally块中完成,以确保即使在发生异常时也能正确关闭资源。

FileInputStream fis = null;
FileOutputStream fos = null;
try {
    fis = new FileInputStream("file.txt");
    fos = new FileOutputStream("copy.txt");
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = fis.read(buffer)) != -1) {
        fos.write(buffer, 0, bytesRead);
    }
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (fis != null) {
        try {
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    if (fos != null) {
        try {
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
使用池化技术(Pooling)

对于昂贵的资源,如数据库连接、线程池等,使用池化技术可以显著提高资源的重用率和系统性能。池化技术维护一组预先初始化的资源,当需要时分配给请求者,使用完毕后归还到池中,而不是每次使用都创建和销毁资源。

监控与诊断

定期监控应用程序的资源使用情况,可以帮助识别潜在的资源泄露或不当使用。使用专业工具(如JVisualVM、Java Mission Control等)进行内存分析、线程监控等,可以辅助定位问题。

最小权限原则

在资源访问和分配时,遵循最小权限原则,即仅给予程序或服务完成其功能所必需的最低权限,有助于减少因资源滥用导致的安全风险。

总之,有效的资源管理不仅提升了程序的健壮性和性能,也是编写高质量、可维护代码的重要组成部分。

这些知识点构成了Java I/O编程的基础,理解和熟练运用它们对于开发涉及文件操作、网络通信等领域的应用程序至关重要。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1823590.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ipad协议已更新

mmtls 24算法,by golang 其他/v1/other POST/v1/other/GetPeopleNearby 查看附近的人 POST/v1/other/GetQrCode 获取二维码 同步消息/v1/ws GET/v1/ws/GetSyncMsg 同步消息,ws协议 消息/v1/message POST/v1/message/AddMessageMgr 添加要发送…

知识表示与推理方法前沿文献报告

✅作业要求: 练习目标:以公开发表的英文学术文献如会议和期刊论文为依据,报告知识表示与推理的前沿研究进展 作业形式: 8-10页的调研报告,以Word或者PDF为文件格式,文件名: 学号 姓名 krdocx/PDF作业完成内容: 1.题目: 文献报告-文…

车道偏离预警系统技术规范(简化版)

车道偏离预警系统技术规范(简化版) 1 系统概述2 预警区域3 功能条件4 显示需求5 指标需求 1 系统概述 车道偏离预警系统工作在中高速驾驶的情况下,当驾驶员因注意力不集中导致车辆偏离本车道时,系统通过光学和声学信号对驾驶员进行…

vue+elementUI实现在表格中添加输入框并校验的功能

背景: vue2elmui 需求: 需要在一个table中添加若干个输入框,并且在提交时需要添加校验 思路: 当需要校验的时候可以考虑添加form表单来触发校验,因此需要在table外面套一层form表单,表单的属性就是ref…

6月17日15点丨解锁大消费品行业收入管理秘籍

在数字化浪潮席卷全球的今天,企业对于收入管理的精细化和智能化需求日益凸显。收入管理作为企业运营的核心环节,对企业的现金流、利润和发展战略至关重要。 在消费品行业,往往拥有大量的销售数据和客户信息,但这些数据往往分散在多个系统和部…

简单了解MySql以及一些简单的应用MySql

MySql基础篇 1、数据模型概述 关系型数据库 概念:建立在关系模型基础上,由多张相互连接的二维表组成的数据库。 特点: 使用表存储数据,格式统一,便于维护使用SQL语言操作,标准统一,使用方便 数…

基于WPF技术的换热站智能监控系统08--实现右上模式控制

1、区域划分 2、UI设计 3、样式及触发器 4、运行效果 走过路过不要错过,点赞关注收藏又圈粉,共同致富,为财务自由作出贡献

【leetcode--单词规律】

题目要求: 跟上一个字符串的思路一致,只是要进行单词的拆分,用.split()函数即可。 class Solution:def wordPattern(self, pattern: str, s: str) -> bool:word s.split()if(len(pattern) ! len(word)):return Falsereturn len(set(patt…

TCP/IP协议,三次握手,四次挥手

IP - 网际协议 IP 负责计算机之间的通信。 IP 负责在因特网上发送和接收数据包。 HTTP - 超文本传输协议 HTTP 负责 web 服务器与 web 浏览器之间的通信。 HTTP 用于从 web 客户端(浏览器)向 web 服务器发送请求,并从 web 服务器向 web …

btrace:binder_transaction+eBPF+Golang实现通用的Android APP动态行为追踪工具

一、简介: 在进行Android恶意APP检测时,需要进行自动化的行为分析,一般至少包括行为采集和行为分析两个模块。其中,行为分析有基于规则、基于机器学习、基于深度学习甚至基于大模型的方案,各有各的优缺点,不…

上传文件生成聊天机器人,实现客服、办公自动化智能体 | Chatopera

从谈论聊天机器人,到谈论智能体,是目前人工智能最炙手可热的话题,这两年最大的变化是大语言模型的应用。聊天机器人曾经很难定制,往往局限于个别行业,同时也只有行业内的领导者、头部企业能定制。比如银行、金融证券、…

火绒安全删除explorer.exe文件造成windows系统异常的问题

问题 过程是这样的,电脑在使用过程中突然就变成了黑色的,任务栏、桌面等都消失了,只有部分程序的窗口。具体如下: 因为,在变化的时候,我有瞟到一眼有个火绒的气泡消息,就感觉是火绒错误的删除…

详解函数动态调用的作用——call

动态调用的作用 类似于其他语言的反射能够开发框架性代码 Call调用语法 (bool success, bytes data) <address>.call(bytes calldata)call是address的方法call返回值(bool success, bytes data)忽视返回值success&#xff0c;会造成严重问题 calldata的结构 call的…

JasperReport-使用Jasper Studio中的table组件制作表格模板

背景&#xff1a; JasperReport 已知调研出的最适合JAVA开发者使用的一款报表模板制作&#xff0c;报表文件生成或导出PDF\Excel\html的最佳框架&#xff08;可以免费使用&#xff09;。 一、Jasper制作表格模板 1.1、制作模板文件 &#xff08;1&#xff09;创建参数 首先…

Ollama+Open WebUI本地部署Llama3 8b(附踩坑细节)

先展示一下最终结果&#xff0c;如下图所示&#xff1a; 1. 添加环境变量 在下载 ollama 之前&#xff0c;先去配置环境变量&#xff0c;确保模型下载到我们想要的地方 win10 和 win11 输入path或者环境变量&#xff1a; 增加系统环境变量 变量名不可更改&#xff0c;必须是O…

Superset 二次开发之Git篇 git cherry-pick

Cherry-Pick 命令是 Git 中的一种功能&#xff0c;用于将特定的提交&#xff08;commit&#xff09;从一个分支应用到另一个分支。它允许你选择性地应用某些提交&#xff0c;而不是合并整个分支。Cherry-Pick 非常适合在需要将特定更改移植到其他分支时使用&#xff0c;例如从开…

基于PointNet / PointNet++深度学习模型的激光点云语义分割

一、场景要素语义分割部分的文献阅读笔记 1.1 PointNet PointNet网络模型开创性地实现了直接将点云数据作为输入的高效深度学习方法&#xff08;端到端学习&#xff09;。最大池化层、全局信息聚合结构以及联合对齐结构是该网络模型的三大关键模块&#xff0c;最大池化层解决了…

SpringBoot 实现 阿里云语音通知(SingleCallByTts)

目录 一、准备工作1.开通 阿里云语音服务2.申请企业资质3.创建语音通知模板&#xff0c;审核通过4.调用API接口---SingleCallByTts5.调试API接口---SingleCallByTts 二、代码实现1.导入依赖 com.aliyun:aliyun-java-sdk-dyvmsapi:3.0.22.创建工具类&#xff0c;用于发送语音通知…

如何部署 Celestia 节点:运行轻节点和全节点

最近几周&#xff0c;Celestia ($TIA) 凭借其模块化数据可用性的基本概念和突破性功能在加密社区引起了轰动。参与网络的方式多种多样&#xff0c;例如将 TIA 与验证器进行质押或在网络上构建应用程序。 用户还可以通过部署节点与区块链进行交互。本指南将解释如何设置和运行 C…

相亲交友APP系统|婚恋交友社交软件|语音聊天平台定制开发

在现代社会&#xff0c;婚恋交友已经成为了人们日常生活中的一项重要任务。为了方便用户进行相亲交友活动&#xff0c;各种相亲交友APP系统和婚恋交友社交软件应运而生。本文将介绍相亲交友APP系统、婚恋交友社交软件的开发以及语音聊天平台的定制开发的相关知识和指导。 一、…