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和非 ...
随机推荐
- python+selenium基础篇,cookie绕过验证码小案例
1.绕过验证码有许许多多的方法,笔者在此介绍其中的一个小方法,原理其实就是获取已登陆了之后的凭证(会话保存在本地的cookie中)再打开另一个页面的使用 2.F12(浏览器开发者调试工具)可以查看的需 ...
- 一、部署监控服务器--安装LNMP环境
1.要求: 本案例要求部署-台Zabbix监控服务器, -台被监控主机,为进一步执行具体的监控任务做准备:1.安装LNMP环境2.源码安装Zabbix3.安装监控端主机,修改基本配置4.初始化Zabb ...
- 使用 Apache Superset 可视化 ClickHouse 数据
Apache Superset是一个强大的BI工具,它提供了查看和探索数据的方法.它在 ClickHouse 用户中也越来越受欢迎. 我们将介绍安装 Superset 的 2 种方法,然后展示如何从 ...
- 惊艳面试官的 Cookie 介绍
Cookie 是什么 Cookie 是用户浏览器保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上. Cookie 主要用于以下三个方面: 会话状态管理(如用户登录 ...
- Redission加锁解锁流程
redission分布式锁的使用 RLock lock = redissonClient.getLock("myLock"); lock.lock(); try { System. ...
- 02 SVN 与 Git 的优缺点
上一篇博客大致聊了聊关于版本控制系统的周边,这一篇我们就来继续唠唠作为近年来最受欢迎的两个版本控制系统的优缺点吧. 聊优缺点之前,先简单了解一下这两个这两个版本控制系统好了: 关于 SVN SVN 概 ...
- 对图数据库(Nebula)进行单元测试时的坑
通过Nebula提供的Java Client完成代码开发后,使用JUnit对其进行单元测试,需要注意几点: 一.不确定性 1.Nebula创建图空间是异步实现的,Nebula将在下一个心跳周期内(默认 ...
- Gerrit+replication 同步Gitlab
配置环境:gerrit 192.168.1.100gitlab 192.168.1.1011.创建秘钥 [root@gerrit ~]# ssh-keygen -m PEM -t rsa 2.添加ho ...
- 如何获取微信小程序for循环的index
在微信小程序开发中,对于wx:for,可以使用wx:for-index="index"来获取数组中的元素的索引值(下标). <view class="item&qu ...
- 无需手动输入命令,简单3步即可在K8S集群中启用GPU!
随着全球各大企业开始广泛采用Kubernetes,我们看到Kubernetes正在向新的阶段发展.一方面,Kubernetes被边缘的工作负载所采用并提供超越数据中心的价值.另一方面,Kubernet ...