IO编程之IO流
Java的IO流是实现输入、输出的基础,它可以方便的实现数据的输入输出操作。在Java中把不同的输入输出源(键盘、文件、网络连接)抽象表述为流(stream)。通过流可以使java程序使用相同的方式访问不同的输入输出源。
一、流的分类
1、按照流的流向分:输入流和输出流
输入流:只能从中读取数据,不能向其写入数据
InputStream/Reader:所有输入流的基类,前者是字节输入流,后者是字符输入流
输出流:只能向其写入数据,不能从中读取数据
OutputStream/Writer:所有输出流的基类,前者是字节输出流,后者是字符输出流
2、按照流的内容分:字节流和字符流
字节流主要是有InputStream/OutputStream作为基类
字符流主要是有Reader/Writer作为基类
3、按照流的角色分:节点流和处理流
从一个特定的IO设备读/写数据的流称为节点流,在已经存在的流进行连接或封装,封装后的流称为处理流。
二、代码测试
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.PushbackReader;
import java.io.RandomAccessFile;
import java.io.Reader;
import org.junit.Test;
public class StreamTest {
/**
* 字节输入流读取文件内容
*
*/
@Test
public void inputStreamTest() {
File f = new File("G://test//a1.txt");
InputStream input = null;
try {
input = new FileInputStream(f);
byte[] bbuf = new byte[1024];
int hasRead = 0;
while((hasRead =input.read(bbuf)) > 0) {
System.out.println(new String(bbuf,0,hasRead));
} } catch (Exception e) {
e.printStackTrace();
}finally {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} /**
* 字符输入流读取文件内容
*/
@Test
public void fileReaderTest() {
File f = new File("G://test//a1.txt");
Reader reader = null;
try {
reader = new FileReader(f);
char[] cbuf = new char[32];
int hasRead = 0;
while((hasRead = reader.read(cbuf))>0) {
System.out.println(new String(cbuf,0,hasRead));
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 使用FileInputStream输入文件,FileOutPutStream输出文件,实现文件复制
*/
@Test
public void fileOutputStreamTest() {
//字节输入流
FileInputStream fis = null;
byte[] bbuf = new byte[1024];
int hasRead = 0;
//字节输出流
FileOutputStream fos = null;
try {
fis = new FileInputStream("G://test//a1.txt");
fos = new FileOutputStream("G://test//a2.txt");
while((hasRead = fis.read(bbuf))>0) {
fos.write(bbuf, 0, hasRead);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
fos.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 字符输出流
*/
@Test
public void FileWriterTest() {
FileWriter fw =null;
try {
fw = new FileWriter("G://test//a3.txt");
fw.write("窗前明月光");
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} /**
* 转换流的使用:InputStreamReader:将字节输入流转换成字符输入流 ,
* OutputStreamWriter将字节输出流转换成字符输出流
*/
public void convertedStreamTest() {
try
(
InputStreamReader reader = new InputStreamReader(new
FileInputStream("G://test//temp.txt"),"UTF-8");
OutputStreamWriter writer = new OutputStreamWriter(new
FileOutputStream("G://test//temp1.txt"),"UTF-8");
)
{
char[] cbuf = new char[32];
int hasRead = 0;
while((hasRead=reader.read(cbuf))>0) {
System.out.print(new String(cbuf, 0, hasRead));
writer.write(cbuf, 0, hasRead);;
}
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 缓冲流BufferReader:具有缓冲功能,它可以一次读取一行文本(以换行符为标识),如果没有读到换行符,则程序堵塞
* 下面程序键盘输入字符串,只有等到按下回车键后,输入的内容才会打印出来
*/
@Test
public void bufferReaderTest() {
try
(
InputStreamReader reader = new InputStreamReader(System.in);
//用缓存流包装输入流
BufferedReader br = new BufferedReader(reader);
)
{
String line = null;
while((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 处理流
* 处理流的优势:1、处理流进行输入输出操作更简单 2、使用处理流的效率更高
*
*使用PrintStream 代替 OutputStream
*PrintStream类的输出功能非常强大,通常如果我们要输出文本内容,应该将输出流包装成PrintStream
*/
@Test
public void printStreamTest() { try (
FileOutputStream fos = new FileOutputStream("G://test//a4.txt");
PrintStream ps = new PrintStream(fos);
)
{
//输出字符串
ps.println("使用PrintStream处理流输出文件");
//输出对象
ps.println(new StreamTest());
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 推回输入流PushbackInputStream和PushbackReader
* 推回输入流都带有一个推回缓冲区,当程序调用这两个推回输入流的unread()方法,系统会把指定数组的内容推回到该缓冲区里,而推回输入流每次调用read()方法时总是先
* 从推回缓冲区中读取内容,只有完全读取了缓冲区的内容,但还没有装满read()所需的数组时才会从原输入流中读取。
* 下面程序利用推回缓冲区,返回文件中"rdb"字符串之前的字符串
*/
@Test
public void pushBackTest() {
try
(
//创建PushbackReader对象,指定缓冲区长度为64
PushbackReader pr = new PushbackReader(new FileReader("G://test//a1.txt"),64);
)
{
char[] cbuf = new char[32];
//用于保存上次读取字符串的内容。
String lastContent = "";
int hasRead = 0;
while((hasRead = pr.read(cbuf))>0) {
//将读取内容转换成字符串
String content = new String(cbuf,0,hasRead);
//用于记录 ‘rdb’字符串的位置
int targetIndex = 0;
if((targetIndex = (content + lastContent).indexOf("rdb"))>0) {
//回推包含‘rdb’的字符串
pr.unread((content+lastContent).toCharArray());
int len = targetIndex > 32? 32:targetIndex;
pr.read(cbuf, 0, len);
System.out.print(new String(cbuf,0,len));
System.exit(0);
}else {
System.out.println(lastContent);
}
}
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 缓冲流BufferReader:具有缓冲功能,它可以一次读取一行文本(以换行符为标识),如果没有读到换行符,则程序堵塞
* 下面程序键盘输入字符串,只有等到按下回车键后,输入的内容才会打印出来
*/
@Test
public void bufferReaderTest() {
try
(
InputStreamReader reader = new InputStreamReader(System.in);
//用缓存流包装输入流
BufferedReader br = new BufferedReader(reader);
)
{
String line = null;
while((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
} /**
* RandomAcessFile类支持"随机访问的方式".程序可以直接跳转到文件的任意地方来读写数据
* 如果我们只想访问文件的部分内容,使用RandomAcessFile更好
* RandomAcessFile允许自由定位文件记录指针,所以RandomAcessFile可以不从开始的地方开始输出,所以RandomAcessFile可以向已经存在的文件
* 后面追加内容。如果程序想在已存在的文件后追加内容,应该使用RandomAcessFile
*
*/
@Test
public void randomAcessFile() { try (
//创建RandomAccessFile对象时需要一个mode参数
//r:以只读方式打开文件,rw:以读写方式打开文件
//rws:以读写方式打开文件,还要求对文件内容或元数据的每个更新都同步写入底层存储设备
//rwd:以读写方式打开文件,还要求对文件内容的每个更新都同步写入到底层存储设备
RandomAccessFile raf = new RandomAccessFile(new File("G://test//a1.txt"), "rw");
)
{
//RandomAccessFile的文件初始位置,初始是0
System.out.println("文件指针初始位置:"+raf.getFilePointer());
//移动文件指针位置,从移动后的位置开始读取文件内容
raf.seek(32);
byte[] bbuf = new byte[32];
int hasRead = 0;
while((hasRead = raf.read(bbuf))>0) {
System.out.println(new String(bbuf,0,hasRead));
} //指针移动到文件最后
raf.seek(raf.length());
//向文件后追加内容
raf.write("追加内容".getBytes()); } catch (Exception e) {
e.printStackTrace();
} }
}
IO编程之IO流的更多相关文章
- python并发编程之IO模型 同步 异步 阻塞 非阻塞
IO浅谈 首先 我们在谈及IO模型的时候,就必须要引入一个“操作系统”级别的调度者-系统内核(kernel),而阻塞非阻塞是跟进程/线程严密相关的,而进程/线程又是依赖于操作系统存在的,所以自然不能脱 ...
- python并发编程之IO阻塞基础知识点
IO模型 解决IO问题的方式方法 问题是:IO操作阻塞程序执行 解决的也仅仅是网络IO操作 一般数据传输经历的两个阶段,如图: IO阻塞模型分类: 阻塞IO 非阻塞IO 多路复用IO 异步IO(爬 ...
- Python并发编程之IO模型
目录 IO模型介绍 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) IO多路复用 异步IO IO模型比较分析 selectors模块 一.IO模型介绍 Stevens ...
- 服务器端网络编程之 IO 模型
引言 从 T 跳槽到 A 之后,我的编程语言也从 C++ 转为 了 Java.在 T 做的偏服务器端开发,而在 A 更偏向于业务开发.上周在 A 公司组内做了一个<服务器端高性能网络编程> ...
- python并发编程之IO模型,
了解新知识之前需要知道的一些知识 同步(synchronous):一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行 #所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调 ...
- 并发编程之IO模型
一.阻塞IO(blocking IO) from concurrent.futures import ThreadPoolExecutor import socket server = socket. ...
- 网络编程之IO模型
IO模型的分类 blocking IO:阻塞IO nonblocking IO:非阻塞IO IO multiplexing:IO多路复用 signal driven IO:异步IO 通常情况下IO默认 ...
- python----并发编程之IO模型
一:IO模型介绍 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个 ...
- Python之旅:并发编程之IO模型
一 IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下:同步.异步.阻塞.非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非 ...
随机推荐
- MindInsight张量可视设计介绍
MindInsight张量可视设计介绍 特性背景 张量可视,能够帮助用户直观查看训练过程中的Tensor值,既支持以直方图的形式呈现Tensor的变化趋势,也支持查看某次step的具体Tensor值. ...
- MindSpore Lite整体架构介绍
MindSpore Lite整体架构介绍 MindSpore Lite框架的总体架构如下所示: 前端(Frontend): 负责模型生成,用户可以通过模型构建接口构建模型,将第三方模型和MindSpo ...
- 马斯克如何颠覆航天? 1/5385成本,c++和python编程!
马斯克如何颠覆航天? 1/5385成本,c++和python编程! 5月31日,经历了重重困难,马斯克的SpaceX载人飞船成功发射,这是美国自2011年以来首次发射载人航天飞船,也是美国进入由商业主 ...
- 前端 JS 之 AJAX 简介及使用
概述 AJAX 是一个缩写,它的全名是 Asynchronous JavaScript and XML,意思就是异步 JavaScript 和 XML,即用JavaScript执行异步网络请求. AJ ...
- 基于TensorFlow的服装分类
1.导包 #导入TensorFlow和tf.keras import tensorflow as tf from tensorflow import keras # Helper libraries ...
- java并发编程JUC第十一篇:如何在线程之间进行对等数据交换
java.util.concurrent.Exchanger可以用来进行数据交换,或者被称为"数据交换器".两个线程可以使用Exchanger交换数据,下图用来说明Exchange ...
- Linkerd 2.10(Step by Step)—将 GitOps 与 Linkerd 和 Argo CD 结合使用
Linkerd 2.10 系列 快速上手 Linkerd v2.10 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traef ...
- SpringCloud-OAuth2(四):改造篇
本片主要讲SpringCloud Oauth2篇的实战改造,如动态权限.集成JWT.更改默认url.数据库加载client信息等改造. 同时,这应该也是我这系列博客的完结篇. 关于Oauth2,我也想 ...
- [Django REST framework - 视图组件之视图基类、视图扩展类、视图子类、视图集]
[Django REST framework - 视图组件之视图基类.视图扩展类.视图子类.视图集] 视图继承关系 详图见文章末尾 视图组件可点我查看 两个视图基类:APIView.GenericAP ...
- 第4章:kubectl命令行管理工具
kubectl --help 查看帮助信息 kubectl create --help 查看create命令帮助信息 命令 描述 create 通过文件名或标准输入创建资源 expose 将一个资源公 ...