欢迎访问宙启技术站
智能推送

Java中常用的I/O操作函数与注意事项

发布时间:2023-06-07 05:39:44

Java中的Input/Output(I/O)操作是Java编程的重要部分。Java I/O操作充分利用了Java的面向对象思想,提供了一组丰富的I/O类库,并提供了许多功能强大的类和接口,使得Java I/O操作变得更加高效、优雅、灵活和可扩展。

Java I/O类库中包含了许多知名的类,如File、InputStream、OutputStream、Reader、Writer等。这些类提供了读取和写入文件、读取和写入流、访问文件系统等众多功能,可以满足大多数Java程序中的输入输出需求。本篇文章介绍了Java中常用的I/O操作函数和注意事项,包括输入/输出流、文件处理、序列化等方面。

I/O输入/输出流

在Java中,输入/输出流分为字节流和字符流两种。字节流主要处理二进制数据,而字符流主要处理字符数据。

字节流包括InputStream、OutputStream、DataInputStream、DataOutputStream等。字符流包括Reader、Writer、BufferedReader、BufferedWriter等。下面分别对常用的I/O流进行介绍。

InputStream

InputStream是Java I/O库中的基类,它提供了从各种来源读取字节的接口。InputStream的常用方法有:

* int read():从输入流中读取一个字节,返回该字节的值,如果到达流的末尾,返回-1。

* int available():返回估计值,表示还有多少字节可以从输入流中读取。

* long skip(long n):跳过n个字节不读取输入流中的数据,返回实际跳过的字节数。

* void close():关闭该输入流并释放与之关联的所有系统资源。

OutputStream

OutputStream是Java I/O库中的基类,它提供了向各种目的地写入字节的接口。OutputStream的常用方法有:

* void write(int b):将一个字节写入到输出流中。

* void write(byte[] b):将字节数组中的所有字节写入到输出流中。

* void flush():刷新输出流,使缓冲区的数据立即写入到目的地。

* void close():关闭该输出流并释放与之关联的所有系统资源。

Reader

Reader是基于字符的输入流,可以一次读取一组字符。Reader的常用方法有:

* int read():从输入流中读取一个字符,返回该字符的值,如果到达流的末尾,返回-1。

* int read(char[] cbuf, int off, int len):从输入流中读取len个字符,并写入到字符数组cbuf中,从数组的第off个位置开始写入,返回实际读取的字符数。

* void close():关闭该输入流并释放与之关联的所有系统资源。

Writer

Writer是基于字符的输出流,可以一次写入一组字符。Writer的常用方法有:

* void write(char[] cbuf, int off, int len):将字符数组cbuf中从off位置开始的len个字符写入到输出流中。

* void flush():刷新输出流,使缓冲区的数据立即写入到目的地。

* void close():关闭该输出流并释放与之关联的所有系统资源。

文件处理

在Java中,可以使用File类来处理文件和文件夹。File类可以创建文件或文件夹、重命名文件或文件夹、删除文件或文件夹,还可以获取文件的信息,如名字、大小、修改时间等。下面介绍一下File类中常用的方法。

File(File parent, String child)

创建一个新的File实例,表示由指定父路径和子路径组成的文件。

File(String pathname)

创建一个新的File实例,表示从指定路径名字符串转换得到的文件。

boolean createNewFile()

创建一个表示文件的新文件,并返回该文件的路径名。

boolean delete()

删除这个文件或目录,并返回true如果这个删除操作成功。

boolean exists()

测试这个文件或目录是否存在,并返回true如果这个文件存在。

String[] list()

返回一个字符串数组,这些字符串指定该目录中的文件和目录。

long length()

返回此文件的长度和字节数。

boolean renameTo(File dest)

将此文件重命名为指定的文件名,如果重命名成功,则返回true,否则返回false。

序列化

序列化是Java中一种将对象转换为永久存储和网络传输的机制。 序列化可以将任何支持序列化接口的对象转换为字节数组,而反序列化就是将字节数组重新转换为对象。

Java中提供了ObjectInput/OutputStream类来实现对象的序列化和反序列化。要使类可序列化,需要在类定义中增加一个serialVersionUID字段。使用序列化时还需要注意以下几点:

* 序列化和反序列化的对象必须是同一个类的实例。

* 序列化期间,对象可以被写入/读取流。如果写入的对象是可变的,则需要记录对象的状态,以便在反序列化期间重建它。

* 在序列化期间,对象引用和静态字段不会被保存,只有对象状态才会被保存。

以下是Java中使用ObjectInput/OutputStream类进行序列化和反序列化的示例代码:

public class SerializeExample implements Serializable {

    private static final long serialVersionUID = 1L;

    private int id;

    private String name;

    public int getId() {

        return id;

    }

    public void setId(int id) {

        this.id = id;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {

        SerializeExample obj = new SerializeExample();

        obj.setId(1);

        obj.setName("test");

        // serialize 

        ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("test.dat"));

        os.writeObject(obj);

        os.close();

        // deserialize

        ObjectInputStream is = new ObjectInputStream(new FileInputStream("test.dat"));

        SerializeExample obj2 = (SerializeExample) is.readObject();

        is.close();

        System.out.println(obj2.getId());

        System.out.println(obj2.getName());

    }

}

注意事项

Java I/O操作过程中需要注意以下几点:

* 在使用I/O操作前应确保输入/输出流是可用的,否则会抛出异常。

* I/O操作通常是阻塞的,程序会在读取或写入数据时被阻塞,直到完成操作或取消操作。因此,应在新的线程中执行I/O操作,以避免阻塞主线程,影响程序的响应性能。

* 当使用内存缓冲区进行I/O操作时,应合理地设置缓冲区大小,以避免出现内存溢出或读取/写入速度缓慢的情况。