哈喽,小伙伴们,欢迎来到小张的频道,今天给大家讲解一下Java中比较重要的一个章节IO流,希望能帮助到小伙伴们。还需要给大家说明的是这是一个系列性文章,如果您想了解更多面试题型,希望大家多多关注小张哦~
1. IO流概览
1.1 IO流分类
1.2 IO流体系
1.3 IO流原理
I/O是Input和Output的缩写,I/O流主要是用来处理数据传输的,如读写文件,网络通信等
输入:读取磁盘文件到程序(内存)中。
输出:将程序(内存)中的数据输出到磁盘上。
下面详细介绍IO流的使用
2. 文件
2.1 文件的创建
package threadcoreknowlodge.io.file;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
/**
* @author zhl
* @date 2023/1/5 15:21
* @description: 演示创建文件的2种方式
*/
public class FileCreate {
@Test
public void createFile1(){
File file = new File("C:\\学习资料", "new1.txt");
try {
file.createNewFile();
System.out.println("创建文件成功!");
} catch (IOException e) {
System.out.println("创建文件失败!");
e.printStackTrace();
}
}
@Test
public void createFile2(){
String filePath = "C:\\学习资料\\new2.txt";
File file = new File(filePath);
try {
file.createNewFile();
System.out.println("创建文件成功!");
} catch (IOException e) {
System.out.println("创建文件失败!");
e.printStackTrace();
}
}
}
2.2 文件对象的信息有哪些?
package threadcoreknowlodge.io.file;
import org.junit.Test;
import java.io.File;
/**
* @author zhl
* @date 2023/1/5 15:49
* @description: 演示获取文件相关信息
*/
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FileInformation {
private static final Logger logger = LoggerFactory.getLogger(FileInformation.class);
@Test
public void GetFileInfo(){
String filePath = "C:\\学习资料\\new1.txt";
File file = new File(filePath);
Logger logger = LoggerFactory.getLogger(FileInformation.class);
logger.info("获取文件名字:"+file.getName());
logger.info("获取文件绝对路径:"+file.getAbsolutePath()); // C:\学习资料\new1.txt
logger.info("获取文件路径:"+file.getPath()); // C:\学习资料\new1.txt
logger.info("获取文件父级目录:"+file.getParent()); // C:\学习资料
logger.info("获取文件大小:"+file.length()); // 0
logger.info("判断文件是否存在:"+file.exists()); // true
logger.info("判断文件是不是一个文件:"+file.isFile()); // true
logger.info("判断文件是不是一个目录:"+file.isDirectory()); // false
}
}
2.3 文件夹的创建与删除
package threadcoreknowlodge.io.file;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
/**
* @author zhl
* @date 2023/1/5 16:12
* @description:
* 1.判断 C:\\学习资料\\new1.txt 是否存在,如果存在就删除
* 2.判断 C:\\学习资料\\demo02 是否存在,存在就删除,否则提示不存在
* 3.判断 C:\\学习资料\\demo\\a\\b\\c 目录是否存在,如果存在就提示已经存在,否则就创建
*/
public class Directory_ {
private static final Logger logger = LoggerFactory.getLogger(Directory_.class);
@Test
public void FileIsExist(){
String filePath = "C:\\学习资料\\new1.txt";
File file = new File(filePath);
if (file.exists()){
file.deleteOnExit();
logger.info("文件删除成功!");
}else {
logger.info("文件 "+file.getName()+" 不存在!");
}
}
@Test
public void DirectoryIsExist(){
String filePath = "C:\\学习资料\\demo02";
File file = new File(filePath);
if (file.exists()){
file.deleteOnExit();
logger.info("目录删除成功!");
}else {
logger.info("目录 "+file.getName()+" 不存在!");
}
}
@Test
public void MulitiDirectoryIsExist(){
String filePath = "C:\\学习资料\\demo\\a\\b\\c";
File file = new File(filePath);
if (file.exists()){
logger.info("文件已经存在");
}else {
logger.info("文件 "+file.getName()+" 不存在!");
logger.info("开始创建文件!");
file.mkdirs();// 创建多级目录
logger.info("文件创建成功!");
}
}
}
3. 访问文件的流
3.1 访问文件的流有哪些?
3.1 FileInputStream/FileOutputStream
package threadcoreknowlodge.io.bytestream;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author zhl
* @date 2023/1/5 17:15
* @description: 演示 FileInputStream and FileOutputStream的使用
* 注意: 字节输入流是一个字节一个字节的读取,效率比较低
*/
public class FileInputStream_ {
private static final Logger logger = LoggerFactory.getLogger(FileInputStream_.class);
@Test
public void FileInputStream1(){
String filePath = "C:\\学习资料\\a.txt";
FileInputStream fis=null;
int nextDataByte =0;
try {
fis = new FileInputStream(filePath);
while ((nextDataByte = fis.read())!=-1){
System.out.println((char)nextDataByte);
};
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
public void FileOutputStream1(){
String filePath = "C:\\学习资料\\b.txt";
FileOutputStream fos = null;
try {
fos = new FileOutputStream(filePath, true);
fos.write("张三".getBytes(),0,3);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// TODO 一次读取8个字节的长度
@Test
public void FileInputAndOutputStream(){
String filePath = "C:\\学习资料\\b.txt";
String outputPath = "C:\\学习资料\\new3.txt";
FileInputStream fis=null;
FileOutputStream fos = null;
byte[] bytes = new byte[8];
int nextDataByte =0;
try {
fis = new FileInputStream(filePath);
while ((nextDataByte = fis.read(bytes))!=-1){
// TODO 这里之所以用GBK的编码方式是因为数据源是GBK编码,如果数据源是utf-8,则使用utf-8编码
logger.info(new String(bytes,0,nextDataByte,"gbk"));
// 写入文件中
fos = new FileOutputStream(outputPath);
fos.write(bytes);
};
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.2 FileReader/FileWriter
package threadcoreknowlodge.io.characterstream;
import org.junit.Test;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* @author zhl
* @date 2023/1/6 12:02
* @description: 演示 FileReader and FileWriter的使用
*/
public class FileReaderAndFileWriter {
@Test
public void readFileByFileReader(){
String filePath = "C:\\学习资料\\a.txt";
String descFilePath = "C:\\学习资料\\e.txt";
FileReader fileReader =null;
FileWriter fileWriter =null;
char[] chars = new char[1024];
int readData =0;
try {
fileReader = new FileReader(filePath);
fileWriter = new FileWriter(descFilePath);
while ((readData = fileReader.read(chars))!=-1){
fileWriter.write(chars,0,readData);
};
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fileReader!=null) fileReader.close();
if (null!=fileWriter) fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
4. 缓冲流
4.1 缓冲流有哪些?
4.2 BufferedInputStream/BufferedOutputStream
package threadcoreknowlodge.io.bufferedstream;
import java.io.*;
/**
* @author zhl
* @date 2023/1/6 13:49
* @description: 演示 BufferedInputStream and BufferedOutputStream的使用
*/
public class BufferedInputStream_ {
public static void main(String[] args) {
String srcFilePath = "C:\\学习资料\\a.txt";
String descFilePath = "C:\\学习资料\\g.txt";
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
byte[] bytes = new byte[1024];
int readData =0;
try {
bis = new BufferedInputStream(new FileInputStream(srcFilePath));
bos = new BufferedOutputStream(new FileOutputStream(descFilePath, true));
while ((readData = bis.read(bytes))!=-1){
// TODO 字节流不需要换行 字符流需要
bos.write(bytes,0,readData);
};
System.out.println("copy完毕!!");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null!=bis) bis.close();
if (null!=bos) bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
4.3 BufferedReader/BufferedWriter
package threadcoreknowlodge.io.bufferedstream;
import java.io.*;
/**
* @author zhl
* @date 2023/1/6 13:38
* @description: 演示 BufferedReafer and BufferedWriter的使用
*/
public class BufferedReader_ {
public static void main(String[] args) {
String srcFilePath = "C:\\学习资料\\a.txt";
String descFilePath = "C:\\学习资料\\f.txt";
BufferedReader br = null;
BufferedWriter bw = null;
char[] chars = new char[1024];
String line;
try {
br = new BufferedReader(new FileReader(srcFilePath));
bw = new BufferedWriter(new FileWriter(descFilePath));
while ((line = br.readLine()) != null) {
System.out.println(line);
bw.write(line);
bw.newLine(); // TODO 换行
}
System.out.println("copy 完成!!!");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != br) br.close();
if (null != bw) bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
5. 对象流
5.1 对象流有哪些?
5.2 ObjectInputStream/ObjectOutputStream
package threadcoreknowlodge.io.objectstream;
import org.junit.Test;
import java.io.*;
import java.util.Properties;
/**
* @author zhl
* @date 2023/1/7 14:40
* @description: 演示ObjectInputStream and ObjectOutputStream使用
*/
public class ObjectStream {
// TODO 演示 ObjectOutputStream 将数据序列化
@Test
public void ObjectOutputStream(){
String filePath ="C:\\学习资料\\data.dat";
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream(filePath));
oos.writeInt(100);
oos.writeBoolean(true);
oos.writeDouble(2.00);
oos.writeUTF("李四");
oos.writeObject(new Dog("哮天犬",3,"中国","黑色"));
System.out.println("数据序列化完毕即保存成功!!");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null!=oos)oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// TODO 演示 ObjectInputStream 将数据反序列化
@Test
public void ObjectInputStream(){
String filePath = "C:\\学习资料\\data.dat";
ObjectInputStream ois =null;
try {
ois = new ObjectInputStream(new FileInputStream(filePath));
System.out.println(ois.readInt());
System.out.println(ois.readBoolean());
System.out.println(ois.readDouble());
System.out.println(ois.readUTF());
System.out.println(ois.readObject());
System.out.println("数据反序列化完毕即读取磁盘文件完毕!!");
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (null!=ois) ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* (1) 要编写一个dog.properties name=tom age=3 country=china color=black
* (2) 编写Dog 类(name,age,country,color) 创建一个dog对象,读取dog.properties 用相应的内容完成属性初始化, 并输出
* (3) 将创建的Dog 对象 ,序列化到 文件 c:\\学习资料\\dog.dat 文件
*/
@Test
public void ObjectStreamCase(){
String filePath = "c:\\学习资料\\dog.dat";
Properties props = new Properties();
try {
props.load(new FileReader("src/main/resources/dog.properties"));
} catch (IOException e) {
e.printStackTrace();
}
Dog dog = new Dog();
dog.setName(props.getProperty("name"));
dog.setAge(Integer.parseInt(props.getProperty("age")));
dog.setCountry(props.getProperty("country"));
dog.setColor(props.getProperty("color"));
// TODO 将对象进行序列化
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream(filePath));
oos.writeObject(dog);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != oos) oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package threadcoreknowlodge.io.objectstream;
import java.io.Serializable;
/**
* @author zhl
* @date 2023/1/6 15:26
* @description:
*/
public class Dog implements Serializable {
private String name;
private int age;
private String country;
private String color;
public Dog(String name, int age, String country, String color) {
this.name = name;
this.age = age;
this.country = country;
this.color = color;
}
public Dog() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
", country='" + country + '\'' +
", color='" + color + '\'' +
'}';
}
}
6. 转换流
6.1 转换流有哪些?
6.1 InputStreamReader/OutputStreamWriter
注意:之所以使用转换流,是因为转换流可以进行编码的设置,防止出现中文乱码的现象
package threadcoreknowlodge.io.transferstream;
import org.junit.Test;
import java.io.*;
/**
* @author zhl
* @date 2023/1/6 16:40
* @description: 演示转换流 InputStreamReader and OutputStreamWriter
*/
public class InputStreamReader_ {
@Test
public void InputStreamReader1() {
String filePath = "C:\\学习资料\\g.txt";
InputStreamReader isr = null;
char[] chars = new char[1024];
int readData = 0;
try {
isr = new InputStreamReader(new FileInputStream(filePath), "gbk");
while ((readData = isr.read(chars)) != -1) {
System.out.println(new String(chars, 0, readData));
}
;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != isr) isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// TODO 采用BufferedReader对InputStreamReader进行升级
@Test
public void InputStreamReader2() {
String srcFilePath = "C:\\学习资料\\g.txt";
String descFilePath = "C:\\学习资料\\h.txt";
BufferedReader br = null;
BufferedWriter bw = null;
char[] chars = new char[1024];
String line;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(srcFilePath), "utf-8"));
while ((line = br.readLine()) != null) {
// 将读取到的数据打印控制台
System.out.println(line);
//
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(descFilePath, true), "utf-8"));
bw.write(line);
bw.newLine();// 换行
bw.flush();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != br) br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
7.打印流
7.1 打印流PrintWriter的使用
package threadcoreknowlodge.io.printstream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author zhl
* @date 2023/1/6 17:18
* @description: 演示 打印流PrintStream 的使用
*/
public class PrintWriter_ {
public static void main(String[] args) {
String filePath = "C:\\学习资料\\f.txt";
PrintWriter writer = null;
try {
writer = new PrintWriter(new FileWriter(filePath));
writer.println("hello,你好~");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null!=writer)writer.close();
}
}
}
7.2 Properties加载配置文件
package threadcoreknowlodge.io.properties;
import org.junit.Test;
import java.io.*;
import java.util.Properties;
/**
* @author zhl
* @date 2023/1/6 17:23
* @description:演示
*/
public class Properties01 {
// TODO 演示用IO流读取配置文件
@Test
public void prop01() {
String filePath = "src/main/resources/mysql.properties";
BufferedReader br =null;
String line;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "utf-8"));
while ((line = br.readLine())!=null){
String[] split = line.split("=");
if ("ip".equalsIgnoreCase(split[0])){
System.out.println("ip="+split[1]);
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null!=br)br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// TODO 演示Properties加载配置文件
@Test
public void prop02() throws IOException {
Properties props = new Properties();
String filePath ="src/main/resources/mysql.properties";
// properties.load(new FileReader(filePath));
// properties.load(new FileInputStream(filePath));
props.load(Properties01.class.getClassLoader().getResourceAsStream("mysql.properties"));
System.out.println("ip="+props.getProperty("ip"));
System.out.println("username="+props.getProperty("username"));
System.out.println("password="+props.getProperty("password"));
}
}
总结: 我们常用的流主要有访问文件的流、缓冲流、转换流等;其中缓冲流优称为处理流,节点流包括:数组节点流、管道节点流、文件节点流和字符串节点流。