IO学习
-
输入流:
- InputStream:FileInputStream,BufferedInputStream,ObjectInputStream
- Reader:FileReader,BufferedReader,InputStreamReader
-
输出流:
- OutputStream:FileOutputStream,BufferedOutputStream,ObjectOutPutStream
- Writer:FileWriter,BufferedWriter,OutputStreamWriter
字符流:Reader,Writer
字节流:InputStream,OutputStream
创建文件的三种方式
new File(String pathname) //根据路径构建一个File对象
new File(File parent,String child) //根据父目录文件+子路径构建
new File(String parent,String child) //根据父目录+子路径构建
createNewFile 创建新文件
获取文件信息
package File;
import java.io.File;
import java.io.IOException;
public class FileTest01 {
public static void main(String[] args) {
//创建文件
File file = new File("D:\\BaiduNetdiskDownload\\Java\\test.txt");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
//获取文件名字
System.out.println("文件名字:" + file.getName());
//获取文件绝对路径
System.out.println("文件绝对路径:" + file.getAbsolutePath());
//获取文件的父目录
System.out.println("文件父目录:" + file.getParent());
//文件大小(字节)
System.out.println("文件大小:" + file.length()); //文件内容abc
//文件是否存在
System.out.println("文件是否存在:" + file.exists());
//是否是文件
System.out.println("是否是文件:" + file.isFile());
//是否是目录
System.out.println("是否是目录:" + file.isDirectory());
}
}
InputStream常用子类
FileInputStream:字节输入流
package InputStreamTest;
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamTest01 {
public static void main(String[] args) {
//使用InputStream来读取文件
FileInputStream file = null;
//int retDate = 0;
int redLen = 0;
try {
file = new FileInputStream("D:\\BaiduNetdiskDownload\\Java\\test.txt");
//一次读取一个字节
/*while ((retDate = file.read()) != -1){
System.out.print((char) retDate);
}*/
//一次读取byte数组
byte[] bytes = new byte[5];
//返回读到的字节数
while ((redLen = file.read(bytes)) != -1){
System.out.print(new String(bytes,0,redLen));
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
file.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileOutputStream:字节输出流
package OutputStreamTest;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamTest01 {
public static void main(String[] args) {
FileOutputStream fos = null;
String filePath = "D:\\BaiduNetdiskDownload\\Java\\a.txt";
try {
fos = new FileOutputStream(filePath); //这种创建文件的方式在写入内容时会覆盖之前的内容
//fos = new FileOutputStream(filePath,true); //这种创建文件的方式在写入内容时会在原来的内容上追加
//写入一个字节
//fos.write('a');
//写入字符串
String str = "hello world!";
//fos.write(str.getBytes());
//write(byte[] b,int off,int len)指定从数组的哪个位置开始写入,写入的长度
fos.write(str.getBytes(),0,5); //hello
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileReader:字符输入流
package FileReaderTest;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderTest01 {
public static void main(String[] args) {
FileReader fr = null;
int readLen = 0;
try {
fr = new FileReader("D:\\BaiduNetdiskDownload\\Java\\test.txt");
char[] chars = new char[10];
while ((readLen = fr.read(chars)) != -1){
System.out.print(new String(chars,0,readLen));
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
FileWriter :字符输出流
package FileWriterTest;
import java.io.FileWriter;
import java.io.IOException;
/**
* Created with IntelliJ IDEA.
*
* @Author: tsl
* @Date: 2022/11/09/14:45
* @Description:
*/
public class FileWriterTest01 {
public static void main(String[] args) {
FileWriter fw = null;
String str = "风雨之后,定见彩虹!";
try {
fw = new FileWriter("src\\note.txt",true); //加入true则表示追加
//写入单个字符
fw.write('a');
//写入指定数组
char[] chars = {'b','c','d'};
fw.write(chars);
//写入数组的自定部分
fw.write(chars,0,2);
//写入字符串
fw.write(str);
//写入字符串的指定部分
fw.write(str,0,4);
//最终结果为:abcdbc风雨之后,定见彩虹!风雨之后
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
两种文件copy
字节流拷贝
package File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Created with IntelliJ IDEA.
*
* @Author: tsl
* @Date: 2022/11/09/10:21
* @Description:
*/
public class FileCopy {
public static void main(String[] args) {
//创建文件输入流
FileInputStream fis = null;
FileOutputStream fos = null;
int readLen = 0;
try {
fis = new FileInputStream("D:\\Music\\music\\迪迦奥特曼 - 电子琴.mp3");
//fos = new FileOutputStream("C:\\Intel\\dj.mp3",true);
fos = new FileOutputStream("C:\\Intel\\迪迦奥特曼 - 电子琴.mp3");
byte[] bytes = new byte[1024];
//第一种方法
/* while (fis.read(bytes) != -1){
fos.write(bytes);
}*/
//第二种方法
while ((readLen = fis.read(bytes)) != -1){
fos.write(bytes,0,readLen);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字符流拷贝
package File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* Created with IntelliJ IDEA.
*
* @Author: tsl
* @Date: 2022/11/09/14:56
* @Description:
*/
public class FileCopyTest {
public static void main(String[] args) {
FileReader fr = null;
FileWriter fw = null;
int readLen = 0;
try {
fr = new FileReader("D:\\BaiduNetdiskDownload\\Java\\test.txt");
fw = new FileWriter("src\\test.txt");
char[] chars = new char[10];
while ((readLen = fr.read(chars)) != -1){
fw.write(chars,0,readLen);
}
} catch (IOException e) {
e.printStackTrace();
}
finally {
try {
if (fr != null){
fr.close();
}
if (fw != null) {
fw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
节点流和处理流
1.节点流可以从一个特定的数据源读写数据,如FileReader、FileWriter
2.处理流(也叫包装流)是“连接”在已存在的流之上,为程序员提供更强大的读写功能,如BufferedReader、BufferedWriter
节点流和处理流的区别和联系
- 节点流是底层流/低级流、可以直接跟数据相接。
- 处理流包装节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出。
- 处理流(也叫包装流)对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连。
处理流的功能主要体现在一下两个方面:
- 性能的提高:主要以增加缓冲的方式来提高输入输出的效率。
- 操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便。
BufferedReader示例:
package Buffered;
import java.io.BufferedReader;
import java.io.FileReader;
public class BufferedReaderTest01 {
public static void main(String[] args) throws Exception{
//创建BufferedReader
BufferedReader br = new BufferedReader(new FileReader("src\\test.txt"));
String readLine ;
while ((readLine = br.readLine()) != null){ //读取一行数据,返回值为null时读取完毕
System.out.println(readLine);
}
//关闭流时只需要关闭BufferedReader,因为底层会自动关闭节点流
br.close();
}
}
BufferedWriter示例:
package Buffered;
import java.io.BufferedWriter;
import java.io.FileWriter;
public class BufferedWriterTest01 {
public static void main(String[] args) throws Exception{
BufferedWriter bw = new BufferedWriter(new FileWriter("src\\bw.txt"));
bw.write("IO流就是牛!");
//插入换行
bw.newLine();
bw.write("IO流就是牛!");
bw.newLine();
bw.write("IO流就是牛!");
bw.newLine();
bw.write("IO流就是牛!");
//关闭流、只需要关闭最外层流
bw.close();
}
}
Buffered拷贝(按字符操作文件)
package Buffered;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
/**
* BufferedReader和BufferedWriter是按字符操作的,不能处理二进制文件
*/
public class BufferedCopy {
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new FileReader("src\\test.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("src\\test01.txt"));
String Line ;
while ((Line = br.readLine()) != null){
bw.write(Line);
bw.newLine();
}
br.close();
bw.close();
}
}
Buffered拷贝(按字节操作文件)
package Buffered;
import java.io.*;
/**
* Created with IntelliJ IDEA.
*
* @Author: tsl
* @Date: 2022/11/11/19:34
* @Description:
*/
public class BufferedCopyPlus {
public static void main(String[] args) throws Exception {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\Music\\music\\不潮不用花钱 - 林俊杰.mp3"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\Intel\\不潮不用花钱 - 林俊杰.mp3"));
byte[] bytes = new byte[1024];
int readLen = 0;
while ((readLen = bis.read(bytes))!= -1){
bos.write(bytes,0,readLen);
}
bis.close();
bos.close();
}
}
对象流ObjectInputStream和ObjectOutputStream
提供了对基本对象或对象类型的序列化和反序列化的方法
ObjectOutputStream提供序列化方法
ObjectInputStream提供反序列化方法
- 序列化就是保存数据时,保存数据的值和数据类型
- 反序列化就是在回复数据时,回复数据的值和数据类型
- 要让某一个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现两个接口之一:Serializable(标记接口没有方法) 和 Externzlizable(该接口有方法需要实现,一般使用Serializable)
使用ObjectOutputStream实现序列化
package SerializableTest;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class ObjectOutputStreamTest01 {
public static void main(String[] args) {
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("D:\\aaaa\\test01.txt"));
oos.write(100);
oos.writeBoolean(true);
oos.writeChar('a');
oos.writeObject("hello world");
oos.writeDouble(0.99);
oos.writeFloat(2.1f);
oos.writeObject(new Dog("皮皮",4));
} catch (IOException e) {
e.printStackTrace();
}finally {
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("序列化完成");
}
}
class Dog implements Serializable {
private String name;
private int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
}
使用ObjectInputStream实现反序列化
package SerializableTest;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
/**
* Created with IntelliJ IDEA.
*
* @Author: tsl
* @Date: 2022/11/12/16:23
* @Description:
*/
public class ObjectInputStreamTest01 {
public static void main(String[] args) {
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("D:\\aaaa\\test01.txt"));
//注意 读取顺序(反序列化)需要和存入顺序一致!否则会抛出java.io.EOFException
int a = ois.read();
boolean b = ois.readBoolean();
char c = ois.readChar();
Object o = ois.readObject();
double d = ois.readDouble();
float f = ois.readFloat();
Object dog = ois.readObject();
//Object o = ois.readObject();
System.out.println(a + "," + b + "," + c + "," + o + "," + d + "," + f + "," + dog);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}finally {
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("反序列化完成");
}
}
注意事项:
- 读写顺序要一致
- 要求实现序列化或反序列化的对象,需要实现Serializable接口
- 序列化的类中建议添加SerialVersionUID,为了提高版本的兼容性
- 序列化对象时,默认将里面所有属性都进行序列化,除了static或transient修饰的成员
- 序列化对象时,要求里面的属性的类型也需要实现序列化接口
- 序列化具备可继承性,也就是说如果一个类已经实现了序列化,那么它的子类也默认实现了序列化
转换流
- InputStreamReader:Reader的子类,可以将InputStream(字节流)包装成Reader(字符流)。
- OutputStreamWriter:Writer的子类,实现将OutputStream(字节流)包装成Writer(字符流)
- 当处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文问题,所以建议将字节流转换为字符流
- 可以在使用时指定编码格式(比如 utf-8 、gbk、gb2312、ISO8859-1等)
InputStreamReader
package transformation;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
/**
* Created with IntelliJ IDEA.
*
* @Author: tsl
* @Date: 2022/11/13/18:52
* @Description:
*/
public class InputStreamReaderTest01 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\aaaa\\test.txt"),"gbk"));
String line = br.readLine(); //因为只有一行数据
System.out.println("读到的数据:" + line);
br.close();
}
}
OutputStreamWriter
package transformation;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
/**
* Created with IntelliJ IDEA.
*
* @Author: tsl
* @Date: 2022/11/13/18:59
* @Description:
*/
public class OutputStreamWriterTest01 {
public static void main(String[] args) throws Exception{
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\aaaa\\test.txt"),"gbk"));
bw.write("风雨之后现彩虹!");
bw.close();
}
}
打印流(打印流只有输出流没有输入流)
PrintStream
package Print;
import java.io.PrintStream;
/**
* Created with IntelliJ IDEA.
*
* @Author: tsl
* @Date: 2022/11/13/20:18
* @Description:
*/
public class PrintStreamTest {
public static void main(String[] args) throws Exception{
PrintStream out = System.out;
out.println("嘻嘻嘻");
//print()方法底层调用的是write()所以可以直接调用write方法
out.write("嘿嘿嘿".getBytes());
//修改输出位置到print.txt文件中
System.setOut(new PrintStream("src\\print.txt"));
//将这句话输出到文件里
System.out.println("你好、Java");
}
}
PrintWriter
package Print;
import java.io.FileWriter;
import java.io.PrintWriter;
/**
* Created with IntelliJ IDEA.
*
* @Author: tsl
* @Date: 2022/11/13/20:27
* @Description:
*/
public class PrintWriterTest {
public static void main(String[] args) throws Exception{
PrintWriter pw = new PrintWriter(new FileWriter("src\\writer.txt"));
pw.println("好得很!");
//如果不关闭流、将不会输出到文件中。
pw.close();
}
}
Properties读文件
常用方法
- load:加载配置文件的键值对到Properties对象
- list:将数据显示到指定设备
- getProperty(key):根据key来获取value
- setProperty(key,value)设置键值对到Properties对象
- store:将Properties中的键值对存储到配置文件,在IDEA中,保存信息到配置文件,如果含有中文,会存储为unicode码
读文件
package Properties;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
/**
* Created with IntelliJ IDEA.
*
* @Author: tsl
* @Date: 2022/11/13/20:56
* @Description:
*/
public class PropertiesTest01 {
public static void main(String[] args) throws IOException {
Properties pro = new Properties();
pro.load(new FileReader("src\\mysql.properties"));
//输出所以内容到控制台
pro.list(System.out);
//根据key来获取value
String port = pro.getProperty("port");
System.out.println("port = " + port);
//设置key-value
pro.setProperty("ip","127.0.0.0");
pro.list(System.out);
}
}
写文件
package Properties;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
/**
* Created with IntelliJ IDEA.
*
* @Author: tsl
* @Date: 2022/11/13/21:06
* @Description:
*/
public class PropertiesTest02 {
public static void main(String[] args) throws IOException {
Properties pro = new Properties();
pro.setProperty("port","3307");
pro.setProperty("user","张三"); //中文会以unicode码来保存 user=\u5F20\u4E09
pro.setProperty("pwd","123321");
//写入文件中
pro.store(new FileOutputStream("src\\mysqlPlus.properties"),"mysql配置文件"); //后面的信息是写入文件后的注释
}
}