[Java基础] 输入输出流

往期回顾

[Java基础] 流程控制

[Java基础] 运算符

[Java基础] 基本数据类型

[Java基础] Java HashMap 的数据结构和底层原理

[Java基础] 面向对象编程

[Java基础] 异常处理机制

[Java基础] 集合框架

目录

分类

字节流

字符流

管道流

打印流

总结

实战

字节流实战

文件读写(FileInputStream 和 FileOutputStream)

基本数据类型读写(DataInputStream 和 DataOutputStream)

对象流(ObjectInputStream 和 ObjectOutputStream)

字符流实战(FileReader 和 FileWriter)

管道流实战(PipedInputStream 和 PipedOutputStream)

打印流实战(PrintStream 和 PrintWriter)

最佳实践

使用 try-with-resources 语句

使用缓冲流

处理异常

使用合适的流类型

使用字符集

分块读写


分类

Java中的输入输出流主要分为四大类:字节流、字符流、管道流和打印流。每种流都有其特定的应用场景,下面详细介绍一下这些流及其应用场景。

字节流

字节流用于处理二进制数据,如图片、音频、视频等。字节流的基类是InputStreamOutputStream

  • FileInputStream 和 FileOutputStream:用于文件的读写操作。
    • 应用场景:读取或写入文件,如复制文件、读取配置文件等。
  • BufferedInputStream 和 BufferedOutputStream:提供缓冲功能,提高读写性能。
    • 应用场景:当需要频繁读写文件时,使用缓冲流可以显著提高性能。
  • DataInputStream 和 DataOutputStream:支持读写基本数据类型。
    • 应用场景:处理包含基本数据类型的数据文件,如二进制文件、配置文件等。
  • ObjectInputStream 和 ObjectOutputStream:支持对象的序列化和反序列化。
    • 应用场景:持久化对象状态,如保存和恢复对象的状态,网络传输对象等。

字符流

字符流用于处理文本数据,以字符为单位进行读写。字符流的基类是ReaderWriter

  • FileReader 和 FileWriter:用于文件的字符读写。
    • 应用场景:读取或写入文本文件,如日志文件、配置文件等。
  • BufferedReader 和 BufferedWriter:提供缓冲功能,可以一次读取一行或多行文本。
    • 应用场景:处理大量文本数据,如日志分析、文本处理等。
  • InputStreamReader 和 OutputStreamWriter:作为字节流和字符流之间的桥梁,使用指定的字符集进行转换。
    • 应用场景:处理不同字符集的文本文件,如读取UTF-8编码的文件。

管道流

管道流用于线程间的通信,实现线程间的协作。

  • PipedInputStream 和 PipedOutputStream:用于线程间的字节数据传输。
    • 应用场景:多线程环境下,一个线程生成字节数据,另一个线程消费字节数据。
  • PipedReader 和 PipedWriter:用于线程间的字符数据传输。
    • 应用场景:多线程环境下,一个线程生成文本数据,另一个线程消费文本数据。

打印流

打印流提供格式化的输出,通常用于标准输出和错误输出。

  • PrintStream 和 PrintWriter:支持格式化的输出。
    • 应用场景:控制台输出、日志记录、调试信息等。

总结

  • 字节流:适用于处理二进制数据,如文件复制、图像处理等。
  • 字符流:适用于处理文本数据,如读写文本文件、日志处理等。
  • 管道流:适用于多线程环境下的数据传输。
  • 打印流:适用于格式化的输出,如控制台输出、日志记录等。

实战

以下是一些关于Java中字节流、字符流、管道流和打印流的实战代码示例。

字节流实战

文件读写(FileInputStream 和 FileOutputStream)

这个示例展示了如何使用字节流从文件中读取数据并将其写入到另一个文件中。

import java.io.FileInputStream;  
import java.io.FileOutputStream;  
import java.io.IOException;  public class ByteStreamExample {  public static void main(String[] args) {  String inputFilePath = "source.txt";  String outputFilePath = "destination.txt";  //这里使用了try-with-resource简化资源管理,这是Java7引入的新特性try (FileInputStream fis = new FileInputStream(inputFilePath);  FileOutputStream fos = new FileOutputStream(outputFilePath)) {  int data;  while ((data = fis.read()) != -1) {  fos.write(data);  }  System.out.println("File copied successfully!");  } catch (IOException e) {  e.printStackTrace();  }  }  
}

在这个例子中,source.txt 是源文件,destination.txt 是目标文件。程序会读取 source.txt 的内容并将其写入 destination.txt

基本数据类型读写(DataInputStream 和 DataOutputStream)

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class DataIOExample {public static void main(String[] args) {String filePath = "C:\\path\\to\\datafile.dat";// 写入基本数据类型try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(filePath))) {dos.writeInt(123);dos.writeDouble(3.14);dos.writeUTF("Hello, World!");} catch (IOException e) {e.printStackTrace();}// 读取基本数据类型try (DataInputStream dis = new DataInputStream(new FileInputStream(filePath))) {int intValue = dis.readInt();double doubleValue = dis.readDouble();String stringValue = dis.readUTF();System.out.println("整数: " + intValue);System.out.println("双精度浮点数: " + doubleValue);System.out.println("字符串: " + stringValue);} catch (IOException e) {e.printStackTrace();}}
}

对象流(ObjectInputStream 和 ObjectOutputStream)

import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;public class ObjectSerializationExample {public static void main(String[] args) {String filePath = "C:\\path\\to\\objectfile.ser";// 序列化对象try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath))) {Person person = new Person("Alice", 30);oos.writeObject(person);} catch (IOException e) {e.printStackTrace();}// 反序列化对象try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath))) {Person person = (Person) ois.readObject();System.out.println("姓名: " + person.getName());System.out.println("年龄: " + person.getAge());} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}}//进行序列化和反序列化的对象必须实现Serializable接口static class Person implements Serializable {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}}
}

字符流实战(FileReader 和 FileWriter)

这个示例展示了如何使用字符流从文件中读取文本数据并将其写入到另一个文件中。

import java.io.BufferedReader;  
import java.io.BufferedWriter;  
import java.io.FileReader;  
import java.io.FileWriter;  
import java.io.IOException;  public class CharacterStreamExample {  public static void main(String[] args) {  String inputFilePath = "input.txt";  String outputFilePath = "output.txt";  try (BufferedReader br = new BufferedReader(new FileReader(inputFilePath));  BufferedWriter bw = new BufferedWriter(new FileWriter(outputFilePath))) {  String line;  while ((line = br.readLine()) != null) {  bw.write(line);  bw.newLine(); // 添加新行  }  System.out.println("File copied successfully!");  } catch (IOException e) {  e.printStackTrace();  }  }  
}

在这个例子中,程序会逐行读取 input.txt 的内容,并将其写入 output.txt,同时保留每行的换行符。

管道流实战(PipedInputStream 和 PipedOutputStream)

管道流允许在线程之间传输数据。以下示例展示了如何使用管道流在两个线程之间发送和接收数据。

import java.io.IOException;  
import java.io.PipedInputStream;  
import java.io.PipedOutputStream;  public class PipedStreamExample {  public static void main(String[] args) {  try (PipedInputStream pin = new PipedInputStream();  PipedOutputStream pout = new PipedOutputStream(pin)) {  // 生产者线程  Thread producer = new Thread(() -> {  try {  String data = "Hello from Producer!";  pout.write(data.getBytes());  pout.close();  } catch (IOException e) {  e.printStackTrace();  }  });  // 消费者线程  Thread consumer = new Thread(() -> {  try {  int data;  StringBuilder sb = new StringBuilder();  while ((data = pin.read()) != -1) {  sb.append((char) data);  }  System.out.println("Received: " + sb.toString());  } catch (IOException e) {  e.printStackTrace();  }  });  producer.start();  consumer.start();  producer.join();  consumer.join();  } catch (IOException | InterruptedException e) {  e.printStackTrace();  }  }  
}

在这个例子中,生产者线程将字符串数据写入 PipedOutputStream,而消费者线程从 PipedInputStream 中读取数据。

打印流实战(PrintStream 和 PrintWriter)

打印流提供了一种方便的方法来格式化输出文本数据。以下示例展示了如何使用PrintStream 输出字符到控制台以及使用 PrintWriter 写字符串到内存。

import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;public class PrintStreamExample {public static void main(String[] args) {// 使用 PrintStream 输出到控制台PrintStream ps = System.out;ps.println("Hello, World!");ps.printf("整数: %d, 双精度浮点数: %.2f\n", 123, 3.14);// 使用 PrintWriter 输出到字符串StringWriter sw = new StringWriter();PrintWriter pw = new PrintWriter(sw);pw.println("Hello, World!");pw.printf("整数: %d, 双精度浮点数: %.2f\n", 123, 3.14);pw.flush();System.out.println("输出到字符串: " + sw.toString());}
}

最佳实践

在Java中处理输入输出流时,遵循一些最佳实践可以提高代码的健壮性、可读性和性能。以下是一些常见的最佳实践:

使用 try-with-resources 语句

try-with-resources 语句可以确保资源在使用完毕后自动关闭,避免资源泄露。这是Java 7引入的一个重要特性。

使用缓冲流

缓冲流可以显著提高读写性能。常见的缓冲流有 BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;public class BufferedInputStreamExample {public static void main(String[] args) {String filePath = "C:\\path\\to\\file.txt";try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath))) {int byteRead;while ((byteRead = bis.read()) != -1) {System.out.print((char) byteRead);}} catch (IOException e) {e.printStackTrace();}}
}

处理异常

合理地处理异常,确保程序在遇到错误时能够优雅地退出或继续运行。

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;public class ExceptionHandlingExample {public static void main(String[] args) {String filePath = "C:\\path\\to\\file.txt";try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {String line;while ((line = br.readLine()) != null) {System.out.println(line);}} catch (IOException e) {System.err.println("文件读取失败: " + e.getMessage());}}
}

使用合适的流类型

根据具体需求选择合适的流类型。例如,处理文本文件时使用字符流(ReaderWriter),处理二进制文件时使用字节流(InputStreamOutputStream)。

使用字符集

在处理文本文件时,显式指定字符集可以避免乱码问题。使用 InputStreamReaderOutputStreamWriter 时可以指定字符集。

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.IOException;public class CharsetExample {public static void main(String[] args) {String filePath = "C:\\path\\to\\file.txt";try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "UTF-8"))) {String line;while ((line = br.readLine()) != null) {System.out.println(line);}} catch (IOException e) {e.printStackTrace();}}
}

分块读写

对于大文件,分块读写可以减少内存消耗和提高性能。

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class ChunkedFileCopyExample {public static void main(String[] args) {String srcFilePath = "C:\\path\\to\\source\\file.txt";String destFilePath = "C:\\path\\to\\destination\\file_copy.txt";try (FileInputStream fis = new FileInputStream(srcFilePath);FileOutputStream fos = new FileOutputStream(destFilePath)) {byte[] buffer = new byte[1024];int length;while ((length = fis.read(buffer)) > 0) {fos.write(buffer, 0, length);}System.out.println("文件复制成功!");} catch (IOException e) {e.printStackTrace();}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

020 elasticsearch7.10.2 elasticsearch-head kibana安装

文章目录 全文检索流程ElasticSearch介绍ElasticSearch应用场景elasticsearch安装允许远程访问设置vm.max_map_count 的值 elasticsearch-head允许跨域 kibana 商品数量超千万,数据库无法使用索引 如何使用全文检索: 使用lucene,在java中唯一…

Nginx(Linux):启动停止Nginx

目录 1、理解Nginx后台进程2、停止Nginx(方式一:使用信号源)2.1 获取master进程号2.1 设置信号源 3、停止Nginx(方式二:使用命令行) 1、理解Nginx后台进程 Nginx后台进程包含master和worker两类进程。 master进程:主要用来管理worker进程&am…

鸿蒙学习笔记--搭建开发环境及Hello World

文章目录 一、概述二、开发工具下载安装2.1 下载开发工具DevEco Studio NEXT2.2 安装DevEco Studio 三、启动软件四、第一个应用Hello World4.1 创建应用4.2 创建模拟器4.3 开启Hyper-v功能4.4 启动虚拟机 剑子仙迹 诗号:何须剑道争锋?千人指&#xff0c…

【Linux】:线程概念

朋友们、伙计们,我们又见面了,本期来给大家带来线程概念相关代码和知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! C 语 言 专 栏:C语言:从入门到精通 数…

9.存储过程安全性博客大纲(9/10)

存储过程安全性博客大纲 引言 在数据库系统中,存储过程是一种预先编写好的SQL代码集合,它被保存在数据库服务器上,可以通过指定的名称来调用执行。存储过程可以包含一系列的控制流语句,如IF条件语句、WHILE循环等,使…

智能汽车制造:海康NVR管理平台/工具EasyNVR多品牌NVR管理工具/设备实现无插件视频监控直播方案

一、背景介绍 近年来,随着网络在我国的普及和深化发展,企业的信息化建设不断深入,各行各业都加快了信息网络平台的建设,大多数单位已经或者正在铺设企业内部的计算机局域网。与此同时,网络也成为先进的新兴应用提供了…

【Git】基本操作+分支管理

Git基本操作 Git仓库创建 Git仓库的基本认知 Git仓库就是一个用来跟踪和管理项目文件变化的地方,其记录了所有的修改历史,可以回退到之前的任何一个历史版本 工作区:正在进行实际操作的文件夹暂存区:临时保存想要提交修改的区域…

【LeetCode:349. 两个数组的交集 + 哈希表】

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

鸿蒙原生应用扬帆起航

就在2024年6月21日华为在开发者大会上发布了全新操作的系统HarmonyOS Next开发测试版,网友们把它称之为“称之为纯血鸿蒙”。因为在此之前鸿蒙系统底层式有两套基础架构的,一套是是Android的AOSP,一套是鸿蒙的Open Harmony,因为早…

计算机毕业设计 基于Python的毕业生去向反馈调查平台的设计与实现 Python毕业设计选题 前后端分离 附源码 讲解 文档

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…

物联网IoT平台 | 物联网IoT平台的定义

物联网IoT平台:定义、发展与应用在当今信息化时代,物联网(Internet of Things,简称IoT)已经成为推动社会进步和产业升级的重要力量。物联网IoT平台,作为连接物理世界与数字世界的桥梁,正逐步改变…

Docker安装Nginx

前提:Docker已安装好,本人使用的为自带docker的云服务器,docker常用命令已掌握,yjj为在根目录创建的一个文件夹,可自行修改对应的目录。 1、安装镜像,可去dockerhub上面找,一般都是组件名称。do…

双十一值得购买超声波清洗机吗?双十一超声波清洗机好物品牌推荐

随着双十一购物狂欢节即将拉开序幕,越来越多的消费者开始关注这个一年一度的购物盛宴。超声波清洗机作为近年来备受关注的家用电器,以其高效、便捷的清洁能力赢得了众多家庭的喜爱。在双十一期间,各大品牌纷纷推出优惠活动,让不少…

红黑树的底层讲解

一、红黑树的介绍 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是红(red)或黑(black)。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红…

通过比较list与vector在简单模拟实现时的不同进一步理解STL的底层

cplusplus.com/reference/list/list/?kwlist 当我们大致阅读完list的cplusplus网站的文档时,我们会发现它提供的接口大致上与我们的vector相同。当然的,在常用接口的简单实现上它们也大体相同,但是它们的构造函数与迭代器的实现却大有不同。…

计算机网络:数据链路层 —— 共享式以太网

文章目录 共享式以太网CSMA/CD 协议CSMA/CD 协议 的基本原理 共享式以太网的争用期共享式以太网的最小帧长共享式以太网的最大帧长共享式以太网的退避算法截断二进制指数退避算法 共享二进制以太网的信道利用率使用集线器的共享式以太网10BASE-T 共享式以太网 共享式以太网是当…

自监督学习:引领机器学习的新革命

引言 自监督学习(Self-Supervised Learning)近年来在机器学习领域取得了显著进展,成为人工智能研究的热门话题。不同于传统的监督学习和无监督学习,自监督学习通过利用未标注数据生成标签,从而大幅降低对人工标注数据…

Modbus TCP 西门子PLC指令以太口地址配置以及 Poll Slave调试软件地址配置

1前言 本篇文章讲了 Modbus TCP通讯中的一些以太网端口配置和遇到的一些问题, 都是肝货自己测试的QAQ。 2西门子 SERVER 指令 该指令是让外界设备主动连接此PLC被动连接, 所以这里应该填 外界设备的IP地址。 这边 我因为是电脑的Modbus Poll 主机来…

反弹shell检测的一些思路

前言 反弹shell是攻击者常用的手段之一,通过反弹Shell,攻击者可以绕过防火墙,获取目标系统的shell访问权限,进行后续的恶意操作。因此,及时检测并阻止反弹Shell行为对于安全防护来说非常重要。本文通过介绍反弹shell的…

Kafka原理剖析之「Purgatory(炼狱 | 时间轮)」

一、前言 本文介绍一下Kafka赫赫有名的组件Purgatory,相信做Kafka的朋友或多或少都对其有一定的了解,至少是听过它的名字。那它的作用是什么呢,用来解决什么问题呢?官网confluent早就有文章对其做了阐述 https://cwiki.apache.o…