java之IO流详解

Java IO(输入/输出)流是Java标准库中用于读取和写入数据的一套功能强大的API。Java IO流主要处理字节流和字符流两种类型的数据。字节流主要用于处理原始二进制数据,如音频、视频和序列化对象等,而字符流主要用于处理文本数据。

Java IO流的核心概念包括输入流(InputStream、Reader)和输出流(OutputStream、Writer),分别用于数据的读取和写入。这些流类都实现了不同的接口和抽象类,以提供不同类型的数据处理能力。

字节流

字节流主要由InputStreamOutputStream两个抽象类及其子类组成。

  • InputStream:这是所有输入字节流类的超类,定义了读取字节数据的基本方法。常用的实现类有FileInputStream(从文件读取数据)、ByteArrayInputStream(从字节数组读取数据)等。
  • OutputStream:这是所有输出字节流类的超类,定义了写入字节数据的基本方法。常用的实现类有FileOutputStream(向文件写入数据)、ByteArrayOutputStream(向字节数组写入数据)等。

字符流

字符流由ReaderWriter两个抽象类及其子类组成,主要用于读写字符数据。

  • Reader:这是所有输入字符流类的超类,提供了读取字符数据的基本方法。常用的实现类有FileReader(从文件读取字符数据)、StringReader(从字符串读取数据)等。
  • Writer:这是所有输出字符流类的超类,提供了写入字符数据的基本方法。常用的实现类有FileWriter(向文件写入字符数据)、StringWriter(向字符串写入数据)等。

缓冲流

Java IO还提供了缓冲流(BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter),它们继承自上述流类,通过内部缓冲区提高IO操作的效率。

转换流

转换流(InputStreamReader和OutputStreamWriter)是字符流和字节流之间的桥梁,它们允许程序以字符流的形式处理字节流,同时可以指定字符集进行编码或解码。

数据流

数据流(DataInputStream和DataOutputStream)允许应用程序以可移植的方式从底层输入流中读取基本Java数据类型,或写入基本数据类型到底层输出流。

对象流

对象流(ObjectInputStream和ObjectOutputStream)允许读写实现了Serializable接口的对象。这种方式常用于对象的序列化和反序列化。

NIO

除了传统的IO流,Java还提供了新的IO(NIO),它支持面向缓冲区的(Buffer),非阻塞的IO操作。NIO提供了更高的性能,特别是在需要处理成千上万连接的高负载网络应用中。

Java IO流提供了丰富且灵活的API,使得读取和写入数据变得既简单又高效。了解和掌握这些不同的流和它们的使用场景对于开发高效的Java应用程序至关重要。
以下是使用Java进行图片下载的示例代码。这个示例使用java.net.URLjava.io包中的类来读取网络上的图片并将其保存到本地文件系统中。请确保你有相应的权限去下载目标URL上的图片。

import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

public class DownloadImage {
    public static void main(String[] args) {
        String imageUrl = "http://example.com/image.jpg"; // 替换为要下载的图片URL
        String destinationFile = "downloaded_image.jpg"; // 保存图片到本地的路径和文件名

        try (InputStream in = new BufferedInputStream(new URL(imageUrl).openStream());
             FileOutputStream fileOutputStream = new FileOutputStream(destinationFile)) {
            byte dataBuffer[] = new byte[1024];
            int bytesRead;
            while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
                fileOutputStream.write(dataBuffer, 0, bytesRead);
            }
            System.out.println("Image downloaded successfully: " + destinationFile);
        } catch (IOException e) {
            System.out.println("Error downloading the image: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

在这个示例中:

  • 使用URL对象来打开目标图片的网络连接。
  • 通过BufferedInputStream读取数据,它添加了缓冲功能以提高读取效率。
  • 使用FileOutputStream将读取的数据写入本地文件。
  • 数据是以字节形式读取和写入的,使用了一个1024字节的缓冲区来存储临时数据。
  • 最后,使用try-with-resources语句自动关闭流,以避免资源泄漏。

请确保替换imageUrl变量的值为实际要下载的图片的URL,同时指定合适的destinationFile路径和文件名,以便正确地保存下载的图片。
下面的Java代码示例用于下载图片,并且每一行都添加了详细的注释来解释代码的作用:

import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

public class DownloadImage {
    public static void main(String[] args) {
        // 定义要下载的图片的URL地址
        String imageUrl = "http://example.com/image.jpg"; // 请替换为实际的图片URL
        // 定义下载图片保存到本地的路径和文件名
        String destinationFile = "downloaded_image.jpg"; // 修改为你希望保存的文件名和路径

        // 使用try-with-resources语句确保所有资源都会被正确关闭
        try (
            // 打开图片URL的流,并使用BufferedInputStream增加缓冲,提高读取效率
            InputStream in = new BufferedInputStream(new URL(imageUrl).openStream());
            // 创建一个向指定文件名写入数据的FileOutputStream
            FileOutputStream fileOutputStream = new FileOutputStream(destinationFile)
        ) {
            // 创建一个临时缓冲区,用于存储从网络读取的数据
            byte dataBuffer[] = new byte[1024];
            int bytesRead;

            // 循环读取数据,直到没有更多数据可读(即返回-1)
            while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
                // 将读取的数据写入文件输出流,从而保存到文件中
                fileOutputStream.write(dataBuffer, 0, bytesRead);
            }
            // 打印一条消息,表示图片已成功下载
            System.out.println("Image downloaded successfully: " + destinationFile);
        } catch (IOException e) { // 捕获并处理可能发生的IO异常
            // 如果下载过程中发生错误,打印错误消息和堆栈跟踪
            System.out.println("Error downloading the image: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

这段代码通过使用Java的标准库中的java.netjava.io相关类来实现图片的下载:

  • URL对象代表了一个远程资源的位置,这里用于指定要下载的图片的URL。
  • BufferedInputStream提供了缓冲功能,可以减少实际进行读取操作的次数,提高了读取数据的效率。
  • FileOutputStream用于将数据写入到文件中。这里它被用来保存从网络上下载的图片。
  • 通过在try资源声明中创建流对象,可以确保无论程序正常结束还是发生异常,资源都会被自动关闭,这是Java 7引入的try-with-resources语句的特性。
  • 在读取和写入过程中使用了一个字节型数组dataBuffer作为缓冲,这样可以批量地处理数据,而不是一次处理一个字节,进一步提高了性能。
  • 使用循环不断从BufferedInputStream读取数据,然后写入FileOutputStream,直到没有更多数据可以读取。这个过程中,read方法返回的bytesRead表示实际读取到的字节数量,当它返回-1时表示没有更多数据可读,即文件已经读取完毕。
  • 如果在下载过程中出现任何IOException,异常处理代码将捕获这个异常并打印错误信息。
  • 22
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Persistence is gold

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值