详解IO流的使用(上)
I/O是输入/输出(Input/Output)的缩写,I/O技术是非常实用的技术,如读/写文件,网络通讯等等。Java的I/O支持通过java.io包下的类与接口来支持。
- I(Input输入),从别的地方(文件、键盘、网络、内存等)读取数据到当前程序中。
- O(Output输出),从程序把数据写/输出到文件、屏幕、网络、内存等中
1.IO流的分类
- 1.从流的方向上可以分为:输入流与输出流。
- 2.根据操作数据的单位可以分为:字节流与字符流。其中字节流:以字节为单位,byte;字符流:以字符为单位,char。
这里需要注意:字符流只能处理纯本文的文件或数据。
纯文本数据:内容全部都是字符
纯本文文件:.txt,.html,.xml,.properties等都是纯文本文件,.doc,.xls,.ppt等都不是。
而字节流使用于任何类型的文件。
- 3.根据功能角色不同,可以分为节点流与处理流。
节点流:和某个节点进行相关,例如:文件流…
处理流:在节点流的基础山,加装饰功能,例如:缓冲流,序列化与反序列化。
其实不管有多少种IO流,最基本的只有四个。IO的四个超级父类,抽象基类。
-
字节输入流:InputStream
-
字节输出流:OutputStream
-
字符输入流:Reader
-
字符输出流:Writer
例如:文件IO流 (1)FileInputStream:文件字节输入流 (2)FileOutputStream:文件字节输出流 (3)FileReader:文件字符输入流 (4)FileWriter:文件字符输出流 例如:缓冲IO流 (1)BufferedInputStream:字节缓冲输入流 (2)BufferedOutputStream:字节缓冲输出流 (3)BufferedReader:字符缓冲输入流 (4)BufferedWriter:字符缓冲输出流
2.文件字符输入输出流:FileReader/FileWriter
文件字符输入输出流:FileReader/FileWriter可以用来处理纯文本文件的输入输出操作,下面对此进行一定的介绍。
2.1 文件字符输入流FileReader
一:读取一个纯文本文件
步骤:
1.选择IO流,创建IO流对象
2.读文件
3.关闭IO流
文件IO操作Reader系列常用方法 |
---|
(1) int read():读取一个字符,正常返回的是该字符的unicode编码值 |
(2)int read(char [] cbuf):读取多个字符,将读取的字符数放到cbuf数组中,最多读取cbuf.lenth个实际本次读取字符的个数 |
(3)int read(char [] cbuf,0,int len):读取多个字符,将读取的字符放在cbuf数组中,从cbuf[off]开始存储,最多读取length个 |
注意:如果流中没有数据可读,返回-1 |
public class MyTest2 {
public static void main(String[] args) throws IOException {
/**
* 文件的IO操作:
* Reader系列:
* (1) int read():读取一个字符,正常返回的是该字符的unicode编码值
* (2)int read(char [] cbuf):读取多个字符,将读取的字符数放到cbuf数组中,最多读取cbuf.lenth个
* 实际本次读取字符的个数
* (3)int read(char [] cbuf,0,int len):读取多个字符,将读取的字符放在cbuf数组中,从cbuf[off]开始存储,最多读取length个
* 注意:如果流中没有数据可读,返回-1
*
*
* 一:读取一个纯文本文件
* 步骤:
* 1.选择IO流,创建IO流对象
* 2.读/写文件
* 3.关闭IO流
*
*/
//1.选择IO流
//因为是操作纯文本文件,这里选择字符流
//因为为读取操作,选择字符输入流FileReader
FileReader fr = new FileReader("1.txt"); //相对路径,相对于当前的项目
//2.读/写文件内容
//数据流向:1.txt-->fr流中-->从流中开始读取
//一次读一个
int data = fr.read();
System.out.println(data);
//一次读多个
char[] arr = new char[10];
while(true){
int len=fr.read(arr);
if (len==-1) {
break;
}
System.out.print(new String(arr,0,len));
}
}
}
2.2 文件字符输出流FileWriter
二:写一些数据到纯文本文件中
步骤:
1.选择IO流,并创建对象
2.写数据
3.关闭IO流
文件IO操作Writer系列常用方法 |
---|
(1)void write(int c):写单个字符 |
(2)void write(char []cbuf):把整个字符数组的内容都写出去 |
(3)void write(char []cbuf,int off,int len):把cbuf[off]开始,len个字符写出去 |
(4)void write(String str):把str内容写出去 |
(5)void write(String str,int off,int len):把str从[off]开始len字符写出 |
(6)void close():关闭 |
(7)void flush():刷新 |
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
public class MyTest3 {
public static void main(String[] args) throws IOException {
/**Writer:
*(1)void write(int c):写单个字符
* (2)void write(char []cbuf):把整个字符数组的内容都写出去
* (3)void write(char []cbuf,int off,int len):把cbuf[off]开始,len个字符写出去
* (4)void write(String str):把str内容写出去
* (5)void write(String str,int off,int len):把str从[off]开始len字符写出去
* (6)void close():关闭
* (7)void flush():刷新
*
*
* 二.写一些数据到纯文本文件中
*1.选择IO流,并创建对象
* 2.读/写数据
* 3.关闭IO流
*
*/
Scanner input = new Scanner(System.in);
System.out.println("请输入一段话:");
String s = input.nextLine();
//1.选择IO流,并创建对象
FileWriter fw = new FileWriter("2.txt",true);
//2.写数据
fw.write("\n");
fw.write(s);
//关闭文件输出流
fw.close();
input.close();
}
}
2.3 用 FileWriter与FileReader来实现纯文本文件的复制
public class MyTest5 {
public static void main(String[] args) throws IOException {
//用 FileWriter与FileReader来实现纯文本文件的复制
File srcFile = new File("G:\\zlb\\IdeaProjects\\2021-04-14 IO流\\2.txt");
File destFile = new File("G:\\zlb\\IdeaProjects\\2021-04-14 IO流\\3.txt");
copyFile(srcFile,destFile);
}
public static void copyFile(File srcFileName, File destFileName) throws IOException {
//复制的过程其实就是文件的输入输出过程
FileReader fr = new FileReader(srcFileName);
FileWriter fw = new FileWriter(destFileName);
int len=0;
char[] ch1 = new char[1024];
while((len=fr.read(ch1))!=-1){
fw.write(ch1,0,len);
fw.flush();
}
fw.close();
fr.close();
}
}
3 文件字节输入输出流:FileInputStram与FileOutputStream
文件字节输入输出流:FileInputStream/FileOutputStream可以用来处理文件的输入输出操作,下面对此进行一定的介绍。
3.1 文件字节输入流:FileInputStram
三:使用字节流来读取纯文本文件
步骤:
1.选择IO流
2.读/写
3.关闭流
文件IO操作InputStream系列常用方法 |
---|
(1)int read():一次读取一个字节,返回本次读取的字节的值 |
(2)int read(byte[] b):一次最多读取多个字节,返回本次实际读取字节数, 读取的字节存在b数组中,从[0]开始,共存储b.lengeth个字节 |
(3)int read(byte[] b,int off,int len):一次最多读取多个字节,返回本次实际读取字节数,读取的字节存在b数组中,从[off]开始,共存储len个字节 |
(4)close():关闭流 |
注意:如果到达流末尾,返回-1 |
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class MyTest {
public static void main(String[] args) throws IOException {
/**IntputStream:
* (1)int read():一次读取一个字节,返回本次读取的字节的值
* (2)int read(byte[] b):一次最多读取多个字节,返回本次实际读取字节数,
* 读取的字节存在b数组中,从[0]开始,共存储b.lengeth个字节
* (3)int read(byte[] b,int off,int len):一次最多读取多个字节,返回本次实际读取字节数,
* 读取的字节存在b数组中,从[off]开始,共存储len个字节
* (4)close()
* 注意:如果到达流末尾,返回-1
*
*
* 三:使用字节流来读取纯文本文件
* 步骤:1.选择IO流
* 2.读/写
* 3.关闭流
*
*
*/
//1.选择IO流
//这里选用的是字节流,因为字节流可以处理任何类型的问题
FileInputStream fis= new FileInputStream(new File("1.txt"));
//2.读取
byte[] bytes = new byte[10];
int len;
while((len=fis.read(bytes))!=-1){
//System.out.println(Arrays.toString(bytes));
//字节数组-->转换为字符串 new String(bytes,0,len)
System.out.println(new String(bytes,0,len));//字节被拆开,可能会乱码
//乱码的原因:本次读了10个字节,就用10个字节去组成字符串显示,出现了字节
}
//关闭流
fis.close();
}
}
3.2 文件字节输入流:FileOutputStram
三:使用字节流来读取纯文本文件
步骤:
1.选择IO流
2.读/写
3.关闭流
文件IO操作OutputStream系列常用方法 |
---|
(1)void wtite(int b):写一个字节 |
(2)void write(byte [] b):写一个字节的所有 |
(3)void write(byte [] b,int off,ine len):写一个字节的一部分 |
(4)void close():关闭流 |
(5)void flush():刷新流 |
public class MyTest3 {
public static void main(String[] args) throws IOException {
/***OutputStream:
*(1)void wtite(int b):写一个字节
*(2)void write(byte [] b):写一个字节的所有
*(3)void write(byte [] b,int off,ine len):写一个字节的一部分
* (4)void close():关闭流
* (5)void flush():刷新流
*
*/
Scanner input = new Scanner(System.in);
System.out.println("请输入一段话:");
String s = input.nextLine();
//1.选择IO流,并创建对象
FileOutputStream fos= new FileOutputStream("1.txt");
//2.写数据
fos.write(s.getBytes());
//关闭文件输出流
fos.close();
}
}
3.3 用 FileOutputStream与FileInputStream来实文件的复制
//复制任意类型的文件,这里需要注意的是需要使用的字节流(以传输图片为例)
//任意类型的文件,只能选择字节流
File srcFile = new File("xingye.jpg");
File destFile = new File("大话西游.jpg");
copyFile(srcFile,destFile);
//复制时不会乱码,是拼在一起进行显示,而且复制前后的编码是一致的
}
public static void copyFile(File srcFileName, File destFileName) throws IOException {
FileInputStream fis = new FileInputStream(srcFileName);
FileOutputStream fos = new FileOutputStream(destFileName);
byte[] bytes = new byte[10];
int len;
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes,0,len);
}
fos.close();
fis.close();
}
}
4.缓冲IO流
- 缓冲IO流:是处理流,负责在其他IO流的基础上增加缓冲能力。
4.1 缓冲字符输入输出流:BufferedReader与BufferedWriter
- BufferedReader除了继承了Reader的那些读的方法,还增加了一个String readLine()读取一行,默认的缓冲区的大小为8192字节/字符。
- BufferedWriter除了继承Writer的那些方法,还增加了写换行符:void newline()
使用缓冲字符输入输出流:BufferedReader与BufferedWriter来复制纯文本文件
import java.io.*;
public class MyTest2 {
public static void main(String[] args) throws IOException {
//利用buffered缓冲流来复制文件
File srcFile = new File("1.txt");
File destFile = new File("4.txt");
copyFile(srcFile,destFile);
}
public static void copyFile(File srcFileName,File destFileName) throws IOException {
FileReader fr = new FileReader(srcFileName);
BufferedReader br = new BufferedReader(fr);
FileWriter fw = new FileWriter(destFileName);
BufferedWriter bw = new BufferedWriter(fw);
//数据流向:1.txt-->fr-->br-->str-->fw-->bw-->4.txt
String str;
while((str=br.readLine())!=null){
bw.write(str);
bw.flush();
//换行
bw.newLine();
}
bw.close();
br.close();
fr.close();
fw.close();
}
}
4.2 缓冲字节输入输出流:BufferedInputStream与BufferedOutputStream
利用缓冲字节输入输出流:BufferedInputStream与BufferedOutputStream来复制文件
import java.io.*;
public class MyTest3 {
public static void main(String[] args) throws IOException {
//利用buffered缓冲流来复制任意类型的数据
File srcFile = new File("D:\\unbtu_install\\ubuntu-18.04\\ubuntu-18.04.1-desktop-amd64.iso");
File destFile = new File("K:\\系统镜像.iso");
copyFile(srcFile,destFile);
}
public static void copyFile(File srcFileName,File destFileName) throws IOException {
FileInputStream fis = new FileInputStream(srcFileName);
BufferedInputStream bis = new BufferedInputStream(fis);//fis比喻成内衣,bis比喻成外套
FileOutputStream fos = new FileOutputStream(destFileName);
BufferedOutputStream bos = new BufferedOutputStream(fos);
//数据流向:1.txt-->fr-->br-->str-->fw-->bw-->4.txt
int len;
byte[] bytes = new byte[1024 *1024];
while((len=bis.read())!=-1){
bos.write(bytes,0,len);
}
bos.close();
bis.close();
fos.close();//先脱外衣
fis.close();//后脱外套
}
}
总结
本节首先对IO流中分类进行介绍,其次重点学习最基本的字符输入输出流、字节输入输出流以及缓冲字节与字符输入输出流,下节还会对其他IO流的使用进行介绍。