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流的更多相关文章

  1. python并发编程之IO模型 同步 异步 阻塞 非阻塞

    IO浅谈 首先 我们在谈及IO模型的时候,就必须要引入一个“操作系统”级别的调度者-系统内核(kernel),而阻塞非阻塞是跟进程/线程严密相关的,而进程/线程又是依赖于操作系统存在的,所以自然不能脱 ...

  2. python并发编程之IO阻塞基础知识点

    IO模型 解决IO问题的方式方法 问题是:IO操作阻塞程序执行 解决的也仅仅是网络IO操作   一般数据传输经历的两个阶段,如图: IO阻塞模型分类: 阻塞IO 非阻塞IO 多路复用IO 异步IO(爬 ...

  3. Python并发编程之IO模型

    目录 IO模型介绍 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) IO多路复用 异步IO IO模型比较分析 selectors模块 一.IO模型介绍 Stevens ...

  4. 服务器端网络编程之 IO 模型

    引言  从 T 跳槽到 A 之后,我的编程语言也从 C++ 转为 了 Java.在 T 做的偏服务器端开发,而在 A 更偏向于业务开发.上周在 A 公司组内做了一个<服务器端高性能网络编程> ...

  5. python并发编程之IO模型,

    了解新知识之前需要知道的一些知识 同步(synchronous):一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行 #所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调 ...

  6. 并发编程之IO模型

    一.阻塞IO(blocking IO) from concurrent.futures import ThreadPoolExecutor import socket server = socket. ...

  7. 网络编程之IO模型

    IO模型的分类 blocking IO:阻塞IO nonblocking IO:非阻塞IO IO multiplexing:IO多路复用 signal driven IO:异步IO 通常情况下IO默认 ...

  8. python----并发编程之IO模型

    一:IO模型介绍  同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个 ...

  9. Python之旅:并发编程之IO模型

    一 IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下:同步.异步.阻塞.非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非 ...

随机推荐

  1. BEP 7:CUDA外部内存管理插件(上)

    BEP 7:CUDA外部内存管理插件(上) 背景和目标 在CUDA阵列接口使得能够共享不同的Python之间的数据库的访问CUDA设备.但是,每个库都与其它库区别对待.例如: Numba在内部管理内存 ...

  2. jemeter压测, 高级应用: 发1万个请求,每个请求参数都不同, 使用CSV数据文件配置

    今天接到一个压测任务, 数据源需要自己从测试环境库中取, 并且使用jemeter 请求, 每个请求参数都不相同 这里使用jemeter的 CSV数据文件来配置: 这样配置好后, 开始发送请求: csv ...

  3. linux文件内容列传行_行转列

    ================ 文件内容列传行_行转列  ================ 一.列转行 1.编辑测试文件 vi log.txt 16:23:00 8.2% 1773620k 16:2 ...

  4. thymeleaf——th:each、th:if的使用

    一.th:each 作用:用于遍历controller层发送过来的集合. 例: Controller代码: @Controller public class HelloController { @Re ...

  5. 【九】Kubernetes 之 Service 概念图文讲解及功能演示

    Service 概念 Kubernetes Service 定义了这样一种抽象:逻辑上的一组 Pod,一种可以访问它们的策略 -- 通常称为微服务. Service 通常是通过 Label Selec ...

  6. RF中在测试用例集上设置标签

    1.有时候我们在执行测试用例时只想执行部分测试用例集下面的测试用例,这时可以在相应的测试用例集中设置标签,然后运行时选择标签执行对应的测试用例 语法: *** Settings *** Force T ...

  7. APP测试的主要内容

    一.功能性测试:依据需求相关的文档编写测试用例进行测试 二.兼容性测试 系统版本:Android,ios 分辨率 网络情况 可用工具:testin 三.安装,升级,卸载测试 首次安装,覆盖安装,卸载后 ...

  8. 三、Tomcat配置文件的介绍

    *允许直接复制另外多份完整的tomcat数据,修改配置保证不冲突,起多个tomcat,优点:其中一个tomcat挂了不影响其他网页 tomcat配置文件server.xml介绍 <Server& ...

  9. 【NX二次开发】NX内部函数,libugui.dll文件中的内部函数

    本文分为两部分:"带参数的函数"和 "带修饰的函数". 浏览这篇博客前请先阅读: [NX二次开发]NX内部函数,查找内部函数的方法 带参数的函数: bool A ...

  10. 会点自动化就要25k? 现在年轻人这么浮躁吗

    面试中一问元素定位就对答如流.一问实际项目框架如何搭建就避重就轻.含糊其辞,这样的自动化实战能力也能拿25K?静待下文: 一.为什么现在自动化测试工资那么高呢? 结合现在的职场环境与企业用人需求,自动 ...