IO流[JAVA]
- 1.文件的基础方法
- 2. IO流简单介绍
- 3. FileInputStream 和 FileOutputStream(字节流方式进行文件读写)
- 4. FileReader 和 FileWriter(字符流进行文件读写)
- 5.字符流包装类BufferedReader 和 BufferedWriter
- 6.字节流包装类BufferedInputStream 和 BufferedOutputStream
- 7.对象包装流ObjectOutputStream 和 ObjectIutputStream
- 8. 字节流转换为字符流(InputStreamReader 和 OutputStreamWriter)
- (1) InputStreamReader
- (2) OutputStreamWriter
- 9. Properties读写配置文件
1.文件的基础方法
(1) 创建文件
需要现在内存中创建一个File对象,然后调用File对象的createNewFile方法才能在磁盘创建文件
在内存中创建一个File对象的三种方式:
方式1:new File(“文件路径”);
方式2:new File(File parentFile, “文件名”);
方式3:new File(“文件父目录路径”, “文件名”);
//方式1
public static void createFile1() throws IOException {
File file = new File("./tmp.txt");
file.createNewFile();
}
//方式2
public static void createFile2() throws IOException {
File file = new File("./dir1");
File file2 = new File(file, "tmp2.txt");
file2.createNewFile();
}
//方式3
public static void createFile3() throws IOException {
File file = new File("./dir1", "tmp3.bak");
file.createNewFile();
}
(2) 获取文件信息
File file = new File("./dir1", "tmp3.bak");
file.createNewFile(); //创建文件
System.out.println("文件名: " + file.getName());
System.out.println("文件的绝对路径:" + file.getAbsolutePath());
System.out.println("文件的父目录: " + file.getParent());
System.out.println("文件大小: " + file.length());
System.out.println("文件是否为目录: " + file.isDirectory());
System.out.println("文件是否为文件: " + file.isFile());
System.out.println("文件是否存在: " + file.exists());
boolean ret = file.delete(); //删除文件
if(ret){
System.out.println("删除成功");
}else{
System.out.println("删除失败");
}
System.out.println("文件是否存在: " + file.exists());
(3) 目录的创建和删除
mkdir: 创建单级目录
mkdirs:创建多级目录
delete:删除目录
示例:
public static void diretoryOperation(){
File file = new File("./demo1");
if(file.exists()){
System.out.println("该目录存在");
}else{
// mkdir 创建单层目录
if(file.mkdir()){
System.out.println("目录创建成功");
}else{
System.out.println("目录创建失败");
}
}
File file2 = new File("./demo2/a/b/c");
if(file2.exists()){
System.out.println("该目录存在");
}else{
// mkdirs:递归创建多级目录
if(file2.mkdirs()){
System.out.println("目录创建成功");
}else{
System.out.println("目录创建失败");
}
}
}
2. IO流简单介绍
IO流指的是输入输出流,输入是将数据从磁盘、数据库等设备输入到内存,输出是将内存的数据存储到固定的位置实现持久化存储。
IO流分为字符流和字节流两种,字符流按照字符读写数据,适用于对于字符数据的读写,而字节流按照字节读写数据,适用于任何文件,字节流对数据的读写不会造成丢失。
3. FileInputStream 和 FileOutputStream(字节流方式进行文件读写)
字节流方式进行文件读写,FileInputStream可以将数据从磁盘读取到内存,FileOutputStream可以将数据从内存写入磁盘中的文件
(1) FileInputStream基本用法
创建FileInputStream对象
//使用File对象创建FileInputStream对象
FileInputStream(File对象);
//根据文件路径创建FileInputStream对象
FileInputStream(文件路径);
读取数据
//读取一个字节的数据,成功返回读取到的数据,到达文件末尾返回-1
int read();
//读取数组arr的所有数据,成功返回读取到的数据长度,到达文件末尾返回-1
int read(byte[] arr);
//读取数组arr的从下标off开始len个字节的数据,成功返回读取到的数据长度,到达文件末尾返回-1
int read(byte[] arr, int off, int len);
示例:
@Test
public void fileInputStreamTest1() throws IOException {
File file = new File("./dir1/hello.txt");
FileInputStream fileInputStream = null;
int readData = 0;
try {
fileInputStream = new FileInputStream(file);
while((readData = fileInputStream.read()) != -1){
System.out.print((char)readData);
}
System.out.println();
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
fileInputStream.close();
}
}
@Test
public void fileInputStreamTest2() throws IOException {
File file = new File("./dir1/hello.txt");
FileInputStream fileInputStream = null;
byte[] readBuffer = new byte[10];
int readLen = -1;
try {
fileInputStream = new FileInputStream(file);
while((readLen = fileInputStream.read(readBuffer)) != -1){
System.out.print(new String(readBuffer, 0, readLen));
}
System.out.println();
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
fileInputStream.close();
}
}
@Test
public void fileInputStreamTest3() throws IOException {
File file = new File("./dir1/hello.txt");
FileInputStream fileInputStream = null;
byte[] readBuffer = new byte[10];
int readLen = -1;
try {
fileInputStream = new FileInputStream(file);
while((readLen = fileInputStream.read(readBuffer, 0, 5)) != -1){
System.out.print(new String(readBuffer, 0, readLen));
}
System.out.println();
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
fileInputStream.close();
}
}
(2) FileOutputStream基本用法
创建FileOutputStream对象
//使用File对象创建FileOutputStream对象,第二个参数为true则为追加方式写入数据,false
//或者不写第二个参数则是覆盖方式写入数据
FileOutputStream(File对象, true/false);
//第一个参数指定文件路径,第二个参数为true则为追加方式写入数据,false
//或者不写第二个参数则是覆盖方式写入数据
FileOutputStream(文件路径, true/false);
写入数据
只有将FileOutputStream关闭才能将数据写入文件
//将指定字节数据写入文件
void write(int data);
//将数组全部数据写入文件
void write(byte[] data);
//将数组从下标off开始len个字节的数据写入文件
void write(byte[] data, int off, int len);
示例:
@Test
public void fileOutputStreamTest01() throws IOException {
File file = new File("./dir1/outputFile.txt");
FileOutputStream fileOutputStream = new FileOutputStream(file);
try {
fileOutputStream.write('C');
} catch (IOException e) {
e.printStackTrace();
} finally {
fileOutputStream.close();
}
}
@Test
public void fileOutputStreamTest02() throws IOException {
File file = new File("./dir1/outputFile.txt");
FileOutputStream fileOutputStream = new FileOutputStream(file);
String str = "hello world";
try {
fileOutputStream.write(str.getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
fileOutputStream.close();
}
}
@Test
public void fileOutputStreamTest03() throws IOException {
File file = new File("./dir1/outputFile.txt");
FileOutputStream fileOutputStream = new FileOutputStream(file, true);
String str = "good afternoon";
try {
fileOutputStream.write(str.getBytes(), 5, str.length() - 5);
} catch (IOException e) {
e.printStackTrace();
} finally {
fileOutputStream.close();
}
}
4. FileReader 和 FileWriter(字符流进行文件读写)
(1) FileReader基本用法
创建FileReader对象
//使用File对象创建FileReader对象
FileReader(File对象);
//使用文件路径创建FileReader对象
FileReader(文件路径)
读取数据
//读取一个字符的数据,成功返回读取到的字符,到达文件末尾返回-1
int read();
//将数组buffer的大小个字符存入数组,成功返回读取到的字符数,到达文件末尾返回-1
int read(char[] buffer);
//从数组的下标off开始存储len个字符,成功返回读取到的字符数,到达文件末尾返回-1
int read(char[] buffer, int off, int len);
示例:
@Test
public void fileReaderTest1() throws IOException {
FileReader fileReader = new FileReader("./dir1/tmp2.txt");
int readData = -1;
while((readData = fileReader.read()) != -1){
System.out.print((char)readData);
}
System.out.println();
fileReader.close();
}
@Test
public void fileReaderTest2() throws IOException {
FileReader fileReader = new FileReader("./dir1/tmp2.txt");
char[] readBuf = new char[50];
int readLen = -1;
while((readLen = fileReader.read(readBuf)) != -1){
System.out.print(new String(readBuf, 0, readLen));
}
System.out.println();
fileReader.close();
}
@Test
public void fileReaderTest3() throws IOException {
FileReader fileReader = new FileReader("./dir1/tmp2.txt");
char[] readBuf = new char[50];
int readLen = -1;
while((readLen = fileReader.read(readBuf, 0, readBuf.length - 1)) != -1){
System.out.print(new String(readBuf, 0, readLen));
}
System.out.println();
fileReader.close();
}
(2) FileWriter基本用法
创建FileWriter对象
//使用File对象创建FileWriter对象
//第二个参数为true表示以追加方式写入,第二个参数为false或没有
//第二个参数表示以覆盖的方式写入
FileWriter(File对象, true/false)
//指定文件路径创建FileWriter对象
//第二个参数为true表示以追加方式写入,第二个参数为false或没有
//第二个参数表示以覆盖的方式写入
FileWriter(文件路径)
写入数据
写入数据必须关闭FileWriter对象才能将数据写入文件
//将字符c写入文件
void write(int c);
//将字符串Str写入文件
void write(String str);
//将字符串Str从下标off开始len个字符写入文件
void write(String str, int off, int len);
//将buffer数组整体写入文件
void write(char[] buffer);
//将buffer数组从下标off开始len个字符写入文件
void write(char[] buffer, int off, int len);
示例:
@Test
public void fileWriterTest01() throws IOException {
FileWriter fileWriter = new FileWriter("./dir1/outputFile.txt");
fileWriter.write('B');
fileWriter.close();
}
@Test
public void fileWriterTest02() throws IOException {
FileWriter fileWriter = new FileWriter("./dir1/outputFile.txt");
fileWriter.write("No matter what, 我爱你");
fileWriter.close();
}
@Test
public void fileWriterTest03() throws IOException {
FileWriter fileWriter = new FileWriter("./dir1/outputFile.txt");
fileWriter.write("No matter how far I go,黑凤梨", 23, 3);
fileWriter.close();
}
@Test
public void fileWriterTest04() throws IOException {
String buffer = new String("2022_12_2_java_learning");
FileWriter fileWriter = new FileWriter("./dir1/outputFile.txt");
fileWriter.write(buffer.toCharArray());
fileWriter.close();
}
@Test
public void fileWriterTest05() throws IOException {
String buffer = new String("2022_12_2_java_learning");
char[] bufferArray = buffer.toCharArray();
FileWriter fileWriter = new FileWriter("./dir1/outputFile.txt");
fileWriter.write(bufferArray, 10, bufferArray.length - 10);
fileWriter.close();
}
5.字符流包装类BufferedReader 和 BufferedWriter
字符流包装类可以提高各种字符流操作的效率,可以使用各种字符流对象进行初始化,具有很强的灵活性
(1) BufferedReader基本用法
创建BufferedReader对象
//使用一个Reader对象来创建,一般使用Reader类的子类对象
BufferedReader(Reader reader)
读取数据
//读取一个字符,成功返回读到的字符,到达流末尾返回-1
int read();
//从数组buf的下标off处开始读取len个字符,成功返回读取到的字符数
//读取到流末尾返回-1
int read(char[] buf, int off, int len);
//读取一行数据,成功返回读取到的数据,到达流末尾返回null
String readLine();
示例:
@Test
public void bufferReadTest1() throws IOException {
BufferedReader bufferedReader = new BufferedReader(new FileReader("./file1.txt"));
String line;
while((line = bufferedReader.readLine()) != null){
System.out.println(line);
}
bufferedReader.close();
}
@Test
public void bufferReadTest2() throws IOException {
BufferedReader bufferedReader = new BufferedReader(new FileReader("./file1.txt"));
int readData;
while((readData = bufferedReader.read()) != -1){
System.out.print((char) readData);
}
System.out.println();
bufferedReader.close();
}
@Test
public void bufferReadTest3() throws IOException {
BufferedReader bufferedReader = new BufferedReader(new FileReader("./file1.txt"));
char[] readData = new char[1024];
int readLen = -1;
while((readLen = bufferedReader.read(readData, 0, 1024)) != -1){
System.out.print(new String(readData, 0, readLen));
}
System.out.println();
bufferedReader.close();
}
(2) BufferedWriter基本用法
创建BufferedWriter对象
//使用Writer对象创建BufferedWriter对象
BufferedWriter(Writer writer)
写入数据
//将字符c写入
void write(int c)
//将buf数组从下标off开始写入len个字符
void write(char[] buf, int off, int len)
//从字符串Str的下标off开始写入len个字符
void write(String str, int off, int len)
//写入一个行分隔符
void newLine();
示例:
@Test
public void bufferedWriterTest1() throws IOException {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("./output.txt", true));
int data = 'c';
System.out.println(data);
bufferedWriter.write(data);
bufferedWriter.close();
}
@Test
public void bufferedWriterTest2() throws IOException {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("./output.txt"));
String data = "java study";
bufferedWriter.write(data);
bufferedWriter.close();
}
@Test
public void bufferedWriterTest3() throws IOException {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("./output.txt"));
String data = "chinese english math";
bufferedWriter.write(data, 0, 7);
bufferedWriter.close();
}
@Test
public void bufferedWriterTest4() throws IOException {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("./output.txt"));
char data[] = {'I', ' ', 'a', 'm', ' ', 'm', 'a', 'n'};
bufferedWriter.write(data);
bufferedWriter.close();
}
@Test
public void bufferedWriterTest5() throws IOException {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("./output.txt"));
char data[] = {'I', ' ', 'a', 'm', ' ', 'a', ' ', 'r', 'e', 'a', 'l', ' ', 'm', 'a', 'n'};
bufferedWriter.write(data, 2, 13);
bufferedWriter.write("Today is a good day");
bufferedWriter.newLine();
bufferedWriter.write("this is end line ");
bufferedWriter.close();
}
6.字节流包装类BufferedInputStream 和 BufferedOutputStream
字节流包装类将字节流对象进行封装,可以提高使用字节流操作数据的效率
(1) BufferedInputStream
创建对象
//使用InputStream对象创建BufferedInputStream对象
BufferedInputStream(InputStream in)
读取数据
//读取一个字节数据,成功返回读取到的字节数据,到达流末尾返回-1
int read();
//从下标off开始读取len个字节到数组readBuf,成功返回读取到的字节数,到达流末尾返回-1
int read(byte[] readBuf, int off, int len);
(2) BufferedOutputStream
创建对象
//使用OutputStream对象创建BufferedOutputStream对象
BufferedOutputStream(OutputStream out)
写入数据
//将一个字节的数据data写入流
void write(int data);
//将buf数组从下标off开始写入len个字节数据到流中
void write(byte[] buf, int off, int len);
(3) 示例
@Test
public void test01() throws IOException {
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
String srcFilePath = "./eye.jpg";
String desFilePath = "./eye2.jpg";
try {
bufferedInputStream = new BufferedInputStream(new FileInputStream(srcFilePath));
bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(desFilePath));
byte[] readBuf = new byte[1024];
int readLen = -1;
while((readLen = bufferedInputStream.read(readBuf)) != -1){
bufferedOutputStream.write(readBuf, 0, readLen);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(bufferedOutputStream != null){
bufferedOutputStream.close();
}
if(bufferedInputStream != null){
bufferedInputStream.close();
}
}
}
@Test
public void test02() throws IOException {
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
String srcFilePath = "./eye.jpg";
String desFilePath = "./eye3.jpg";
try {
bufferedInputStream = new BufferedInputStream(new FileInputStream(srcFilePath));
bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(desFilePath));
int readData = -1;
while((readData = bufferedInputStream.read()) != -1){
bufferedOutputStream.write(readData);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(bufferedOutputStream != null){
bufferedOutputStream.close();
}
if(bufferedInputStream != null){
bufferedInputStream.close();
}
}
}
7.对象包装流ObjectOutputStream 和 ObjectIutputStream
对象包装流的作用是将对象序列化和反序列化,序列化是将对象转换为字节,反序列化是将字节转换为对象
(0) 注意事项
- 能进行的序列化的类对象对应的类必须实现Serializable接口
- 基础数据类型如int、char、double、String的包装类已经实现了Serializable接口,可以直接使用
- 序列化顺序和反序列化顺序必须保持一致
- 自定义类型中每个成员变量都必须能够进行序列化,否则自定义类型不能序列化
(1) ObjectOutputStream
创建ObjectOutputStream对象
//使用OutputStream 对象创建ObjectOutputStream
ObjectOutputStream(OutputStream out)
序列化常见方法
//将对象object序列化
writeObject(Object object);
//将数据按照对应格式序列化
void writeInt();
void writeFloat();
void writeDouble();
void writeChar();
//将字符串按照UTF-8编码方式序列化
void writeUTF(String str);
(2) ObjectIutputStream
创建ObjectIutputStream 对象
//使用InputStream 对象创建ObjectInputStream
ObjectInputStream(InputStream in)
反序列化常见方法
//读取对应类型数据
int readInt();
double readDouble();
char readChar;
//按照UTF-8编码方式读取数据
String readUTF();
//读取对象
Object readObject();
(3) 示例
Person
public class Person implements Serializable {
private String name_;
private int age_;
public Person(String name_, int age) {
this.name_ = name_;
this.age_ = age;
}
@Override
public String toString() {
return "Person{" +
"name_='" + name_ + '\'' +
", age=" + age_ +
'}';
}
}
ObjectOutputStreamTest
public class ObjectOutputStreamTest {
public static void main(String[] args) throws IOException {
String outputPath = "./output.txt";
String hobby = "唱歌";
int time = 1;
double money = 9888.99;
Person person = new Person("张麻子", 34);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(outputPath));
objectOutputStream.writeUTF(hobby);
objectOutputStream.writeInt(time);
objectOutputStream.writeDouble(money);
objectOutputStream.writeObject(person);
objectOutputStream.close();
}
}
ObjectInputStreamTest
public class ObjectInputStreamTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
String filePath = "./output.txt";
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filePath));
String hobby = objectInputStream.readUTF();
int time = objectInputStream.readInt();
double money = objectInputStream.readDouble();
Person person = (Person)objectInputStream.readObject();
System.out.println("hobby:" + hobby);
System.out.println("time:" + time);
System.out.println("money:" + money);
System.out.println("person:" + person);
}
}
8. 字节流转换为字符流(InputStreamReader 和 OutputStreamWriter)
当通过字节流读取数据时,有些情况下会因为编码方式的不同导致读取或写入的数据和预期不同,因此可以使用InputStreamReader和OutputStreamWriter进行转换,将字节流转换为指定编码方式的字符流,从而正确操作数据
(1) InputStreamReader
创建InputStreamReader 对象
InputStreamReader 对象可以当做字符流对象来使用
//使用InputStream对象创建InputStreamReader对象,并制定编码方式
// charsetName可以是utf-8、gbk等
InputStreamReader(InputStream in, String charsetName)
示例
@Test
public void inputStreamTransferTest() throws IOException {
String filePath = "./inputfile.txt";
String charSet = "gbk";
FileInputStream fileInputStream = new FileInputStream(filePath);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, charSet);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String line = bufferedReader.readLine();
System.out.println(line);
bufferedReader.close();
}
(2) OutputStreamWriter
创建OutputStreamWriter对象
//使用OutputStream 对象创建OutputStreamWriter对象,并制定编码方式
// charsetName可以是utf-8、gbk等
OutputStreamWriter(OutputStream out, String charsetName);
示例
@Test
public void outputStreamTransferTest() throws IOException {
String charSet = "gbk";
String filePath = "./output2.txt";
FileOutputStream fileOutputStream = new FileOutputStream(filePath);
String data = "今天是java文件模块学习的最后一天";
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, charSet);
outputStreamWriter.write(data);
outputStreamWriter.close();
}
9. Properties读写配置文件
在java中经常使用配置文件,因此需要一种高效操作配置文件的工具类,Properties就是这样一个工具类
(1) 配置文件的格式
- 配置文件的内容都是kv键值对
- 一个键值对占一行
- 每个键值对的格式是key=value,key和=之间没有空格,value和=之间没有空格
- key默认是字符串,不需要加双引号
(2) 常见方式
//设置输入流,也就是内容是从哪里读取的
void load(InputStream inStream);
void load(Reader reader);
//根据key获取到对应的value
String getProperty(String key);
//设置key对应的value,如果key存在则是修改,不存在就是新增
//key存在则返回key对应的旧的Value,不存在则返回null
Object setProperty(String key, String value);
//将数据保存到对应的文件中, comments是文件内容的注释
void store(OutputStream out, String comments);
void store(Writer writer, String comments);
//将文件内容输出到指定输出流
void list(PrintStream out);
void list(PrintWriter out);
(3) 示例
配置文件内容
mysql.properties
ip=192.168.120.111
dbname=testdb
user=root
passwd=123
读取配置文件
@Test
public void propertiesReadTest() throws IOException {
String filePath = "./mysql.properties";
Properties properties = new Properties();
//加载输入文件
properties.load(new FileReader(filePath));
//根据key获取value
System.out.println("ip:" + properties.getProperty("ip"));
System.out.println("user:" + properties.getProperty("user"));
//将配置文件内容输出到控制台
properties.list(System.out);
}
将数据写入未创建的配置文件
@Test
public void propertiesWriteTest() throws IOException {
String filePath = "./info.properties";
Properties properties = new Properties();
properties.setProperty("user", "user1");
properties.setProperty("passwd", "wffjepoqjf");
properties.setProperty("invalidTime", "三年");
properties.store(new FileWriter(filePath), "个人信息");
}
修改配置文件内容
@Test
public void propertiesWriteTest2() throws IOException {
String filePath = "./mysql.properties";
Properties properties = new Properties();
properties.load(new FileReader(filePath));
//修改value
properties.setProperty("user", "张三");
//设置新键值对
properties.setProperty("season", "winter");
properties.store(new FileWriter(filePath), "database info");
}