IO流
什么是IO流
- I:Input
- O:Output
- 通过IO可以完成硬盘文件的读和写
IO流的分类
1.按照流的方式进行分类
输入流(InputStream):
- 往内存中去,叫输入(Input),或者叫做读(Read)。
输出流(OutputStream):
- 从内存中出来,叫输出(Output),或者叫做写(Write)。
2.按照读取数据的方式进行分类
按字节的方式读取数据:
一次读取1个字节byte,等于一次读取8个二进制。这种流是万能的,什么类型都可以读取。包括:文本文件、图片、声音、视频等。
按字符的方式读取数据:
一次读取一个字符,这种流是为了方便读取普通文本文件而存在的,这种流只能读取纯文本文件,不能读取图片、声音、视频。
IO流的四大家族
按照上面的分类方式可具体将IO流分为四大类,分别是:
- 字符输入流:java.io.Reader
- 字符输出流:java.io.Writer
- 字节输入流:java.io.InputStream
- 字节输出流:java.io.OutputStream
识别方法
在Java类名中以Stream结尾的是字节流,以Reader/Writer结尾的都是字符流
两点注意
- 所有的流都实现了java.io.Closeable接口,都有close()方法,都是可关闭的。流是一个管道,连接内存和硬盘,用完一定要关闭,否者会消耗很多资源
- 所有的流都实现了java.io.Flushable接口,都有flush()方法,都是可刷新的。在输入流的最终输出之后,一定要刷新一下,这个刷新表示将流内剩余未输出的数据强行输出(相当于清空管道),如果不刷新可能导致数据丢失
需要掌握的流
*java.io.包下需要掌握的16个流
该如何选择哪种IO流?
如果数据通过Window自带的记事本软件打开,我们还可以读懂里面的内容,就使用字符流,否则使用字节流。 如果你不知道该使用哪种类型的流,就使用字节流。
代码演示
首先创立一个.text文件,并输入一串字符“abcde” 创建路径一定要记得
字节输入流
使用java.io.FileInputStream
InputStream:字节输入流基类,抽象类是表示字节输入流的所有类的超类。
常用方法
序号 | 方法名 | 解释 |
---|---|---|
1 | abstract int read() | 从输入流中读取数据的下一个字节 |
2 | int read(byte[] b) | 从输入流读取一些字节数,并将它们存储到缓冲区 b |
3 | int read(byte[] b, int off, int len) | 从输入流读取最多 len 字节的数据到一个字节数组。 |
4 | void close() | 关闭此输入流并释放与该流关联的所有系统资源 |
使用read()方法
package com.gao.IO;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Test {
public static void main(String[] args) {
//创建一个输入流
FileInputStream fileInputStream = null;
try{
fileInputStream = new FileInputStream("Text");
int readDate=0;
//逐字节读取,当文本被读完时,read()方法返回-1,循环结束
while((readDate=fileInputStream.read())!=-1){
System.out.println(readDate);
}
}catch (FileNotFoundException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}finally {
//在finally块中关闭流
if(fileInputStream!=null){
try {
fileInputStream.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
}
运行结果
使用read(byte[] b)方法,比read()方法快
package com.gao.IO;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Test1 {
public static void main(String[] args) {
//创建一个输入流
FileInputStream fileInputStream = null;
try{
fileInputStream = new FileInputStream("Text");
//准备一个4个长度的byte数组,一次最多读4个字节,这里大小可以任意,但是太大会导致内存溢出
byte[] bytes=new byte[4];
int readDate=0;
//逐字节读取,当文本被读完时,read()方法返回-1,循环结束
while((readDate=fileInputStream.read(bytes))!=-1){
System.out.println(new String(bytes,0,readDate));
}
}catch (FileNotFoundException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}finally {
//在finally块中关闭流
if(fileInputStream!=null){
try {
fileInputStream.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
}
字节输出流
使用java.io.FileOutputStream,与java.io.FileInputStream类似
package com.gao.IO;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test2 {
public static void main(String[] args) {
//创建一个输入流
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try{
fileInputStream = new FileInputStream("Text");
fileOutputStream = new FileOutputStream("Output.txt");
byte[] bytes=new byte[4];
int readDate=0;
//逐字节读取,当文本被读完时,read()方法返回-1,循环结束
while((readDate=fileInputStream.read(bytes))!=-1){
//一边读,一边写
fileOutputStream.write(bytes,0,readDate);
}
fileOutputStream.flush();
}catch (FileNotFoundException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}finally {
//在finally块中关闭流
if(fileInputStream!=null){
try {
fileInputStream.close();
}catch (IOException e){
e.printStackTrace();
}
}
if(fileOutputStream!=null){
try {
fileOutputStream.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
}
字符输入流
使用java.io.FileReader
package com.gao.IO;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Test3 {
public static void main(String[] args) {
FileReader fileReader=null;
try {
fileReader=new FileReader("Text");
//准备一个4个长度的char数组,这里大小可以任意,但是太大会导致内存溢出
char[] chars=new char[4];
int readCount=0;
while((readCount=fileReader.read(chars))!=-1){
for (int i = 0; i < readCount; i++) {
System.out.println(chars[i]);
}
}
}catch (FileNotFoundException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}finally {
if(fileReader!=null){
try{
fileReader.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
}
缓冲流
使用这个流我们可以不用自己定义byte[]数组来承接,自带缓冲
使用java.io.BufferedReader
节点流
当一个流的构造方法中需要一个流时,这个被传送进来的流叫:节点流
缓冲流
外部负责包装的流叫:包装流或处理流
package com.gao.IO;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Test4 {
public static void main(String[] args) {
FileReader fileReader= null;
try {
fileReader = new FileReader("Text");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//在这里FileReader为节点流,BufferedReader为缓冲流
BufferedReader bufferedReader=new BufferedReader(fileReader);
String s=null;
while (true){
try {
if (!((s=bufferedReader.readLine())!=null)) break;
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(s);
}
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
转换流
转换流就是中间起作用的那个流
package com.gao.IO;
import java.io.*;
public class Test5 {
public static void main(String[] args) {
BufferedWriter out= null;
try {
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("Text2")));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
out.write("燕山大学");
} catch (IOException e) {
e.printStackTrace();
}
try {
out.write("里仁学院");
} catch (IOException e) {
e.printStackTrace();
}
try {
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
FileReader fileReader=null;
try {
fileReader=new FileReader("Text2");
//准备一个4个长度的char数组,这里大小可以任意,但是太大会导致内存溢出
char[] chars=new char[4];
int readCount=0;
while((readCount=fileReader.read(chars))!=-1){
for (int i = 0; i < readCount; i++) {
System.out.println(chars[i]);
}
}
}catch (FileNotFoundException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}finally {
if(fileReader!=null){
try{
fileReader.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
}
数据流
用DataOutputStream写文件只能用DataInputStream去读
package com.gao.IO;
import java.io.*;
public class Test6 {
public static void main(String[] args) {
DataOutputStream dataOutputStream= null;
try {
dataOutputStream = new DataOutputStream(new FileOutputStream("Text1"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
byte b=100;
short s=200;
int i=300;
long l=400L;
float f=3.0F;
double d=3.14;
boolean a=false;
char c='a';
try {
dataOutputStream.writeByte(b);
} catch (IOException e) {
e.printStackTrace();
}
try {
dataOutputStream.writeShort(s);
} catch (IOException e) {
e.printStackTrace();
}
try {
dataOutputStream.writeInt(i);
} catch (IOException e) {
e.printStackTrace();
}
try {
dataOutputStream.writeLong(l);
} catch (IOException e) {
e.printStackTrace();
}
try {
dataOutputStream.writeFloat(f);
} catch (IOException e) {
e.printStackTrace();
}
try {
dataOutputStream.writeDouble(d);
} catch (IOException e) {
e.printStackTrace();
}
try {
dataOutputStream.writeBoolean(a);
} catch (IOException e) {
e.printStackTrace();
}
try {
dataOutputStream.writeChar(c);
} catch (IOException e) {
e.printStackTrace();
}
try {
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
dataOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
DataInputStream dataInputStream= null;
try {
dataInputStream = new DataInputStream(new FileInputStream("Text1"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
byte b1=dataInputStream.readByte();
System.out.println(b1);
} catch (IOException e) {
e.printStackTrace();
}
try {
short s1=dataInputStream.readShort();
System.out.println(s1);
} catch (IOException e) {
e.printStackTrace();
}
try {
int i1=dataInputStream.readInt();
System.out.println(i1);
} catch (IOException e) {
e.printStackTrace();
}
try {
long l1=dataInputStream.readLong();
System.out.println(l1);
} catch (IOException e) {
e.printStackTrace();
}
try {
float f1=dataInputStream.readFloat();
System.out.println(f1);
} catch (IOException e) {
e.printStackTrace();
}
try {
double d1= dataInputStream.readDouble();
System.out.println(d1);
} catch (IOException e) {
e.printStackTrace();
}
try {
char c1= dataInputStream.readChar();
System.out.println(c1);
} catch (IOException e) {
e.printStackTrace();
}
try {
boolean a1= dataInputStream.readBoolean();
System.out.println(a1);
} catch (IOException e) {
e.printStackTrace();
}
try {
dataInputStream.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
标准输出流
本质时控制台输出,但是我们可以改变输出方向,一般将其作为日志工具类
定义Logger类
package com.gao.IO;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.SimpleTimeZone;
public class Logger {
public static void log(String msg) {
try {
//指定一个日志文件
PrintStream printStream= null;
printStream = new PrintStream(new FileOutputStream("log.txt",true));
//改变输出方向
System.setOut(printStream);
//获取当前时间
Date date=new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str= simpleDateFormat.format(date);
System.out.println(date+":"+msg);
printStream.close();
}catch (FileNotFoundException e){
e.printStackTrace();
}
}
}
定义测试类
package com.gao.IO;
public class Test7 {
public static void main(String[] args) {
Logger.log("程序正常运行");
Logger.log("xxxxxxx");
}
}