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. 将DataTable转成Json字符串

    1 public string ToJson(DataTable tbl) 2 { 3 if (tbl.Rows.Count > 0) 4 { 5 DataRowCollection rows ...

  2. Android 小知识点笔记

    获取 view 的位置 View.getLocationInWindow(int[] location) 一个控件在其父窗口中的坐标位置 View.getLocationOnScreen(int[] ...

  3. 【转】【NX二次开发】UFUN进度中断,单击停止可中断此操作

    队长的博客: https://www.cnblogs.com/nxopen2018/p/13174207.html 显示此对话框,点击可中断操作: 用到的ufun函数: UF_ABORT_ask_fl ...

  4. ES6中的新数据类型——Symbol

    今天小编和大家来聊一聊es6中新增的一个原始数据类型Symbol.在es5中原始数据类型(基本数据类型)有以下六种:Undefind.Null.Bool. String.Number.Object.今 ...

  5. TCP/IP协议 (图解+秒懂+史上最全)

    文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...

  6. 再有人问你HashMap,把这篇文章甩给他

    搞定HashMap 作为一个Java从业者,面试的时候肯定会被问到过HashMap,因为对于HashMap来说,可以说是Java==集合中的精髓==了,如果你觉得自己对它掌握的还不够好,我想今天这篇文 ...

  7. git stash回退

    目录 1.起因 2. 问题出现 3.修复 4. 注意 1.起因 这个问题要从今天刚遇到的事儿说起,昨晚代码出了个乌龙事件,本来正在dev分支进行新功能的开发,但是测试出现的问题是在release 分支 ...

  8. rust漫游 - 写时拷贝 Cow<'_, B>

    rust漫游 - 写时拷贝 Cow<'_, B> Cow 是一个写时复制功能的智能指针,在数据需要修改或者所有权发生变化时使用,多用于读多写少的场景. pub enum Cow<'a ...

  9. js笔记8

    1.js数据类型 基本数据类型:string.undefined.null.boolean.nember 引用数据类型:object.array.function 二者的区别? 基本的数据类型就是简单 ...

  10. MIT6.828 Lab3 User Environments

    Lab3 这个实验分成了两个大部分. 1. PartA User Environments and Exception Handling kernel使用Env这个数据结构来trace每一个user ...