
字符输入输出流对应于:文本文件(.txt,.java,.c,.cpp)
字节输入输出流对应于:非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,…)
注意:转换流的理解
理解记忆:
站在显示的角度
1 把接受来的字节解码成我们看的见的字符展现出来就是解码 inputstreamReader
2 把将要输出去的字符转化为字节便于保存起来就是编码, outputstreamWriter
InputStreamReader:将一个字节的输入流转换为字符的输入流
解码:字节、字节数组 —>字符数组、字符串
OutputStreamWriter:将一个字符的输出流转换为字节的输出流
编码:字符数组、字符串 —> 字节、字节数组
说明:编码决定了解码的方式
4.输入、输出的标准化过程
4.1 输入过程
① 创建File类的对象,指明读取的数据的来源。(要求此文件一定要存在)
② 创建相应的输入流,将File类的对象作为参数,传入流的构造器中
③ 具体的读入过程:
创建相应的byte[] 或 char[]。
④ 关闭流资源
说明:程序中出现的异常需要使用try-catch-finally处理。
4.2 输出过程
① 创建File类的对象,指明写出的数据的位置。(不要求此文件一定要存在)
② 创建相应的输出流,将File类的对象作为参数,传入流的构造器中
③ 具体的写出过程:
write(char[]/byte[] buffer,0,len)
④ 关闭流资源
说明:程序中出现的异常需要使用try-catch-finally处理。
案例:
基本字节和字符输入输出流:
package com.javabase.javabase.IO;
import com.sun.org.apache.bcel.internal.generic.IFNULL;
import org.junit.Test;
import java.io.*;
import java.sql.SQLOutput;
/**
* @Author ShawnYang
* @Date 2019-09-24 13:54
* @Description TODO
* 修改人:
* 修改时间:
* 修改备注:
*/
public class IOTest {
/**
* @Author ShawnYang
* @Date 2019/9/24 0024 17:42
* @Description 文件输入流测试
* 修改人:
* 修改时间:
* 修改备注:
* 实现注意:
*/
@Test
public void testFileReader1() {
//1.File类的实例化
File file = new File("D:\\github\\javabase\\javabase-exception\\src\\main\\resources\\hello.txt");
FileReader fileReader = null;
try {
//2.FileReader流的实例化
fileReader = new FileReader(file);
char[] cbuf = new char[20];
int len;
//3.读入的操作
//read(char[] cbuf):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾,返回-1
//最后一次读到文件的末尾,返回读进去的字符数,最后再返回-1(类似于一个都没读进去就返回-1
while ((len = fileReader.read(cbuf)) != -1) {
// 注意这里i<len 而不是 i<cbuf.length
for (int i = 0; i < len; i++) {
//注意不是println 不然每个字符后面都有一个回车
// System.out.println(cbuf[i]);
System.out.print(cbuf[i]);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileReader != null) {
try {
//4.资源的关闭
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* @Author ShawnYang
* @Date 2019/9/24 0024 17:42
* @Description 文本输入流测试2
* 修改人:
* 修改时间:
* 修改备注:
* 实现注意:
*/
@Test
public void testFileReader2() {
//1 File类的实例化
File fIle = new File("D:\\github\\javabase\\javabase-exception\\src\\main\\resources\\hello.txt");
//2 流的实例化
FileReader fileReader = null;
try {
fileReader = new FileReader(fIle);
//3 读取流
char[] cbuf = new char[5];
int len = 0;
// 输出方式一
while ((len = fileReader.read(cbuf)) != -1) {
String str = new String(cbuf, 0, len);
System.out.print(str);
}
// 输出方式二 使用stringBuffer
// StringBuffer stringBuffer = new StringBuffer();
// while ((len = fileReader.read(cbuf)) != -1) {
// String str = new String(cbuf, 0, len);
// stringBuffer.append(str);
// }
// System.out.println(stringBuffer);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* @Author ShawnYang
* @Date 2019/9/24 0024 17:43
* @Description 文本输出流测试
* 修改人:
* 修改时间:
* 修改备注:
* 实现注意:
*/
@Test
public void testFileWrite(){
// 1 创建文件对象,当然也可以根据url创建File对象
File file = new File("D:\\github\\javabase\\javabase-exception\\src\\main\\resources\\hellocopy2.txt");
// 2 创建流对象
// File对应的硬盘中的文件如果不存在,在输出的过程中,会自动创建此文件。
// File对应的硬盘中的文件如果存在:
// 如果流使用的构造器是:FileWriter(file,false) / FileWriter(file):对原文件的覆盖,默认为false
// 如果流使用的构造器是:FileWriter(file,true):不会对原文件覆盖,而是在原文件基础上追加内容
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter(file);
// 3 写出到文件
fileWriter.write("i have a dream\n");
fileWriter.write("from Martin King");
} catch (IOException e) {
e.printStackTrace();
}finally {
// 4 关闭流
if (fileWriter != null) {
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* @Author ShawnYang
* @Date 2019/9/24 0024 17:42
* @Description 文本输入输出流测试,对于文本文件(.txt,.java,.c,.cpp),使用字符流处理
* 修改人:
* 修改时间:
* 修改备注:
* 实现注意:
*/
@Test
public void testFileReaderAndWriter() {
// 1 创建文件对象
File srcFile = new File("D:\\github\\javabase\\javabase-exception\\src\\main\\resources\\hello.txt");
File destFile = new File("D:\\github\\javabase\\javabase-exception\\src\\main\\resources\\hellocopy4.txt");
// 2 创建流对象
FileReader fileReader = null;
FileWriter fileWriter =null;
try {
fileReader = new FileReader(srcFile);
fileWriter = new FileWriter(destFile);
// 3 读入与写出
char[] cbuff = new char[5];
int len;
while ((len=fileReader.read(cbuff)) != -1) {
// 下面的输出结果,“返回每次读入cbuf数组中的字符的个数。如果达到文件末尾,返回末尾,返” 注意最后的四个字符的重复,最后一次读取只是覆盖了部分字段(读取了所有长度
// 所有要按照len读取
System.out.println(cbuff);
fileWriter.write(cbuff,0,len);
// 不刷新的话文字出不来
fileWriter.flush();
}
} catch (Exception e) {
e.printStackTrace();
}finally {
// 4 流关闭
if (fileWriter != null) {
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* @Author ShawnYang
* @Date 2019/9/24 0024 17:43
* @Description 非文本输入输出流测试,对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,...),使用字节流处理
* 修改人:
* 修改时间:
* 修改备注:
* 实现注意:
*/
@Test
public void testInputStreamAndOutputStream(){
// 1 创建文件对象
File src = new File("D:\\aaa.jpg");
File dest = new File("D:\\aaa2.jpg");
// 2 创建流
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream=null;
try {
fileInputStream = new FileInputStream(src);
fileOutputStream = new FileOutputStream(dest);
// 3 读入和写出数据
byte[] bytes = new byte[5];
int len;
while((len=fileInputStream.read(bytes))!=-1){
fileOutputStream.write(bytes, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
// 4 流的关闭
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
在基本输入输出流的基础上包装处理流:缓冲流
package com.javabase.javabase.IO;
import org.junit.Test;
import java.io.*;
/**
* @Author ShawnYang
* @Date 2019-09-24 16:01
* @Description TODO
* 修改人:
* 修改时间:
* 修改备注:
*/
public class BufferIOTest {
/**
* @Author ShawnYang
* @Date 2019/9/24 0024 18:16
* @Description 缓冲流处理文本文件
* 修改人:
* 修改时间:
* 修改备注:
* 实现注意:
*/
@Test
public void BufferFileReaderAndWriterTest() {
// 1 建立文件对象
File srcFile = new File("D:\\github\\javabase\\javabase-exception\\src\\main\\resources\\hello.txt");
// 输出文件可以不存在,程序运行后会自动创建
File destFile = new File("D:\\github\\javabase\\javabase-exception\\src\\main\\resources\\hellocopy5.txt");
BufferedReader bufferedReader = null;
BufferedWriter bufferedWriter = null;
try {
// 2 建立流对象
// 2.1 建立节点流
FileReader fileReader = new FileReader(srcFile);
FileWriter fileWriter = new FileWriter(destFile);
// 2.2 在节点流的基础上建立,建立处理流(这里是缓存流)
bufferedReader = new BufferedReader(fileReader);
bufferedWriter = new BufferedWriter(fileWriter);
// 3 读入和写出数据
// 方法一
// char[] cbuff = new char[1024];
// int len;
// while ((len = bufferedReader.read(cbuff)) != -1) {
//// 也可以一个一个字符写入,效率低
//
// bufferedWriter.write(cbuff);
//// 不要忘记了flush,把处理流中的数据刷线到文件中
// bufferedWriter.flush();
// }
// 方法二:FileReader类没有readline方法
String data;
// bufferedReader.readLine()一行一行读取 以换行符作为结束标识
while ((data = bufferedReader.readLine()) != null) {
// data中不包括换行符,bufferedWriter.newLine(); 该方法有等同于换行符的作用
bufferedWriter.write(data + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 4 流关闭,外层流关闭后,内层流会自动关闭
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bufferedWriter != null) {
try {
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* @Author ShawnYang
* @Date 2019/9/24 0024 18:43
* @Description 非文件输入输出流
* 修改人:
* 修改时间:
* 修改备注:
* 实现注意:
*/
@Test
public void BufferdInputStreamAndOutputStreanTest() {
// 1 建立文件对象
File srcFile = new File("D:\\aaa.jpg");
// 输出文件可以不存在,程序运行后会自动创建
File destFile = new File("D:\\aaa3.jpg");
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
try {
// 2 建立流对象
// 2.1 建立节点流
InputStream inputStream = new FileInputStream(srcFile);
FileOutputStream fileOutputStream = new FileOutputStream(destFile);
// 2.2 在节点流的基础上建立,建立处理流(这里是缓存流)
bufferedInputStream = new BufferedInputStream(inputStream);
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
// 3 读入和写出数据
byte[] bbuff = new byte[1024];
int len;
while ((len = bufferedInputStream.read(bbuff)) != -1) {
// 也可以一个一个字符写入,效率低
bufferedOutputStream.write(bbuff);
// 不要忘记了flush,把处理流中的数据刷线到文件中
bufferedOutputStream.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 4 流关闭,外层流关闭后,内层流会自动关闭
if (bufferedInputStream != null) {
try {
bufferedInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bufferedOutputStream != null) {
try {
bufferedOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
在基础流的基础上包装处理流:装换流:
package com.javabase.javabase.IO;
import org.junit.Test;
import java.io.*;
/**
* @Author ShawnYang
* @Date 2019-09-24 19:03
* @Description TODO
* 修改人:
* 修改时间:
* 修改备注:InputStreamReader:将一个字节的输入流转换为字符的输入流
* 解码:字节、字节数组 --->字符数组、字符串
*
* OutputStreamWriter:将一个字符的输出流转换为字节的输出流
* 编码:字符数组、字符串 ---> 字节、字节数组
*
* 说明:编码决定了解码的方式
*/
public class TransferIOTest {
@Test
public void TransferIOTest(){
//1.造文件
File file1 = new File("D:\\github\\javabase\\javabase-exception\\src\\main\\resources\\hello.txt");
File file2 = new File("D:\\github\\javabase\\javabase-exception\\src\\main\\resources\\hellocopy6.txt");
FileInputStream fis = null;
FileOutputStream fos = null;
InputStreamReader isr = null;
OutputStreamWriter osw = null;
try {
//2 造流
fis = new FileInputStream(file1);
fos = new FileOutputStream(file2);
isr = new InputStreamReader(fis,"utf-8");
osw = new OutputStreamWriter(fos,"gbk");
//3.读写过程
char[] cbuf = new char[20];
int len;
while((len = isr.read(cbuf)) != -1){
osw.write(cbuf,0,len);
}
} catch (Exception e) {
e.printStackTrace();
}
//3.关闭资源
if (isr != null) {
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (osw != null) {
try {
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
网络IO连接:
package com.javabase.javabase.IO;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
/**
* @Author ShawnYang
* @Date 2019-09-24 19:39
* @Description TODO
* 修改人:
* 修改时间:
* 修改备注:
*/
public class UrlTest {
public static void main(String[] args) throws IOException {
//1 和file类似 创建url对象
URL url = new URL("http://localhost:8888/aaa3.jpg");
// 2 创建连接,获取连接(新增的步骤)
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.connect();
// 3 获取流对象,url所对应的数据会包含在流对象中
InputStream inputStream = urlConnection.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream("D:\\aaa4.jpg");
// 4 输入和输出数据
byte[] bytes = new byte[1024];
int len;
while((len=inputStream.read(bytes))!=-1){
fileOutputStream.write(bytes, 0, len);
}
}
}
补充:
syetem.in 输入的是字节流
public class ClientTest {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String expStr = getExpStr(); // a+b
HashMap<String, Integer> var = getValue(expStr);// var {a=10, b=20}
Calculator calculator = new Calculator(expStr);
System.out.println("运算结果:" + expStr + "=" + calculator.run(var));
}
// 获得表达式
public static String getExpStr() throws IOException {
System.out.print("请输入表达式:");
return (new BufferedReader(new InputStreamReader(System.in))).readLine();
}
// 获得值映射
public static HashMap<String, Integer> getValue(String expStr) throws IOException {
HashMap<String, Integer> map = new HashMap<>();
for (char ch : expStr.toCharArray()) {
if (ch != '+' && ch != '-') {
if (!map.containsKey(String.valueOf(ch))) {
System.out.print("请输入" + String.valueOf(ch) + "的值:");
String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
map.put(String.valueOf(ch), Integer.valueOf(in));
}
}
}
return map;
}
}
本文深入讲解Java中的IO流概念,区分字符输入输出流与字节输入输出流的应用场景,详细介绍基本字节和字符输入输出流的使用方法,包括读取与写入文本文件和非文本文件的具体操作流程。
262

被折叠的 条评论
为什么被折叠?



