一、Java I/O
文件、内存、键盘--->程序--->文件、内存、控制台
二、文件
相关记录或放在一起的数据的集合
思考:
Java程序如何访问文件属性?
解答:
Java API:java.io.File类
三、File类
File类的常用方法
方法名称 | 说明 |
---|---|
boolean exists( ) | 判断文件或目录是否存在 |
boolean isFile( ) | 判断是否是文件 |
boolean isDirectory( ) | 判断是否是目录 |
String getPath( ) | 返回此对象表示的文件的相对路径名 |
String getAbsolutePath( ) | 返回此对象表示的文件的绝对路径名 |
String getName( ) | 返回此对象表示的文件或目录的名称 |
boolean delete( ) | 删除此对象指定的文件或目录 |
boolean createNewFile( ) | 创建名称的空文件,不创建文件夹 |
long length() | 返回文件的长度,单位为字节, 如果文件不存在,则返回 0L |
1、判断文件是否存在及文件类型
package javaapidemo0130.demo01;
import java.io.File;
public class FileDemo01 {
public static void main(String[] args) {
/*
* 首先,在电脑D盘新建文件夹Java2408,在里面新建demo.txt test文件夹 文件名为abc.txt的文件夹
* 使用File类的对象,指向电脑某个磁盘中的文件或者文件夹
* */
File file1 = new File("D:\\Java2408\\test");
File file2 = new File("D:/Java2408/demo.txt");
File file3 = new File("D:/Java2408/abc.txt");
// 并不知道文件是文件夹还是文本文档 需要通过方法
File file4 = new File("D:/Java2408/aaaa.txt");
// File类中常用的方法
// boolean exists( )判断文件或目录是否存在
boolean result1 = file1.exists();
System.out.println("file1对象指向的文件或目录存在:" + result1); // true
System.out.println("file2对象指向的文件或目录存在:" + file2.exists()); // true
System.out.println("file3对象指向的文件或目录存在:" + file3.exists()); // true
System.out.println("file4对象指向的文件或目录存在:" + file4.exists()); // false
System.out.println("------ ------ ------");
// boolean isFile( )判断是否是文件
// boolean isDirectory( )判断是否是目录
System.out.println("file1指向demo.txt文本");
System.out.println("file1对象指向的路径表示一个文件:" + file1.isFile()); // false
System.out.println("file1对象指向的路径表示一个目录:" + file1.isDirectory()); // true ???
System.out.println("file2指向test文件夹");
System.out.println("file2对象指向的路径表示一个文件:" + file2.isFile()); // true
System.out.println("file2对象指向的路径表示一个目录:" + file2.isDirectory()); // false
System.out.println("file3指向abc.txt文件夹");
System.out.println("file3对象指向的路径表示一个文件:" + file3.isFile()); // false
System.out.println("file3对象指向的路径表示一个目录:" + file3.isDirectory()); // true
System.out.println("file4对象指向路径不存在");
System.out.println("file4对象指向的路径表示一个文件:" + file4.isFile()); // false
System.out.println("file4对象指向的路径表示一个目录:" + file4.isDirectory()); // false
}
}
2、创建文件
package javaapidemo0130.demo01;
import java.io.File;
import java.io.IOException;
public class FileDemo02 {
public static void main(String[] args) {
File file1 = new File("D:/Java2408/a.txt"); // 此时a.txt是不存在的
// 判断file1对象指向的文件是否存在,如果不存在就创建文件,如果存在就删除文件
if (file1.exists()) {
// 删除
boolean result1 = file1.delete();
System.out.println("文件删除成功:" + result1);
} else {
// 创建文件
try {
boolean result2 = file1.createNewFile(); // 声明异常或者处理异常
System.out.println("文件创建成功:" + result2);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
File file2 = new File("D:/Java2408/b");
try {
boolean result3 = file2.createNewFile();
System.out.println("文件创建成功:" + result3); // true 创建的b为文件类型
} catch (IOException e) {
throw new RuntimeException(e);
}
// 创建目录
}
}
3、创建目录
package javaapidemo0130.demo01;
import java.io.File;
public class FileDemo03 {
public static void main(String[] args) {
/*
* boolean mkdir()创建此抽象路径名指定的目录。
* boolean mkdirs()创建此抽象路径名指定的目录,包括所有必需但不存在的父目录
*/
File file1 = new File("D:/Java2408/a");
System.out.println("file1对象指向的目录创建成功:" + file1.mkdir()); // 创建目录,目录名为a成功
File file2 = new File("D:/Java2408/b/c/d");
// System.out.println("file2对象指向的目录创建成功:" + file2.mkdir()); // false
System.out.println("file2对象指向的目录创建成功:" + file2.mkdir());
/*
* mkdir()方法和mkdirs()方法的区别:
* mkdir()创建的目录,要求其父目录已经存在
* mkdirs()创建的目录,如果其父目录,该方法也会将父目录创建出来,但是有一个前提:所有父目录都不存在
* */
}
}
4、查看文件内容长度
package javaapidemo0130.demo01;
import java.io.File;
public class FileDemo04 {
public static void main(String[] args) {
File file1 = new File("D:/Java2408/a.txt"); // a.txt文本文件的内容为:Hello起风了
// 获取file对象指向的文件内容长度
// long length():返回由此抽象路径名表示的文件的长度
long length = file1.length();
System.out.println("file对象指向的文件内容的长度为:" + length); // file对象指向的文件内容的长度为:14
// 其中每个文字占三个字符
}
}
5、绝对路径与相对路径
package javaapidemo0130.demo01;
import java.io.File;
import java.io.IOException;
public class FileDemo05 {
public static void main(String[] args) throws IOException {
// 获取相对路径与绝对路径
File file1 = new File("D:/Java2408/a.txt");
// String getAbsolutePath():返回此抽象路径名的绝对路径名字符串
// String getPath():将此抽象路径名转换为一个路径名字符串
String absolutePath = file1.getAbsolutePath();
System.out.println("file1对象指向的文件的绝对路径:" + absolutePath); // file1对象指向的文件的绝对路径:D:\Java2408\a.txt
String path = file1.getPath();
System.out.println("file1对象指向的文件的相对路径:" + path); // file1对象指向的文件的相对路径:D:\Java2408\a.txt
File file2 = new File("aaa.txt");
// 创建file2文件
file2.createNewFile();
// 获取绝对路径与相对路径
System.out.println("file2对象指向的文件的绝对路径:" + file2.getAbsolutePath()); // file2对象指向的文件的绝对路径:D:\DJavaStudy\StudyJavaAPI\aaa.txt
System.out.println("file2对象指向的文件的相对路径:" + file2.getPath()); // file2对象指向的文件的相对路径:aaa.txt
}
}
6、查看目录下的文件或目录
package javaapidemo0130.demo01;
import java.io.File;
import java.util.Arrays;
public class FileDemo06 {
public static void main(String[] args) {
File file = new File("D:/Java2408");
// 查看file对象指向的目录有哪些文件或目录
// String[] list() :返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录
String[] string = file.list();
System.out.println(Arrays.toString(string)); // [a, a.txt, abc.txt, b, demo.txt, test]
}
}
四、流
如何读写文件?通过流读写文件
流是一组有序的数据序列
以先进先出方式发送信息的通道
OutputStream类(抽象类)
InputStream类(抽象类)
Writer类(抽象类)
Reader类(抽象类)
1、FileInputStream类(InputStream类的子类)
构造方法:
FileInputStream(File file): 通过打开一个到实际文件的连接来创建一个 FileInputStream
,该文件通过文件系统中的 File
对象 file
指定
FileInputStream(String name):通过打开一个到实际文件的连接来创建一个 FileInputStream
,该文件通过文件系统中的路径名 name
指定
常用方法:
int available() | 返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数 |
int read() | 从此输入流中读取一个数据字节 |
int read(byte[] b) | 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中 |
int read(byte[] b, int off, int len) | 从此输入流中将最多 len 个字节的数据读入一个 byte 数组中 |
package javaapidemo0130.demo02;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputStreamDemo01 {
public static void main(String[] args) {
// 创建FileInputStream类对象
FileInputStream fileInputStream = null;
File file = new File("D:/Java2408/aa.txt");
try {
// 创建FileInputStream类对象
fileInputStream = new FileInputStream(file); // 传入file对象
// 通过fileInputStream对象调用方法从指定的文件中读取
// int available()返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数
int available = fileInputStream.available();
System.out.println("从指定的文件中大概能读取到的数据内容数量:" + available);
//读取内容
/*
int num1 =fileInputStream.read();
System.out.println((char)num1);
int num2 =fileInputStream.read();
System.out.println((char)num2);
int num3 =fileInputStream.read();
System.out.println((char)num3);
int num4 =fileInputStream.read();
System.out.println((char)num4);
int num5 =fileInputStream.read();
System.out.println((char)num5);
int num6 =fileInputStream.read();
System.out.println((char)num6);
int num7 =fileInputStream.read();
System.out.println((char)num7);
int num8 =fileInputStream.read();
System.out.println(num8);
*/
/*while (fileInputStream.read()!=-1) {
int num = fileInputStream.read();
System.out.print((char)num + " "); // b d f h g l n p
}*/
// 上面的循环操作确实可以读取文件中的数据,但是会出现隔一个读取一个的情况
// 因为在这里调用了两次read()方法,第一次只读取没有输出,第二次读取并输出
int num;
while ((num = fileInputStream.read()) != -1) {
System.out.print((char) num + " ");
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
// 不管前面的操作中异常有没有或者有没有处理,流最终都要关闭
try {
if (fileInputStream != null) {
fileInputStream.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
package javaapidemo0130.demo02;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputStreamDemo02 {
public static void main(String[] args) throws IOException {
// 创建FileInputStream类对象
FileInputStream fileInputStream = new FileInputStream("D:/Java2408/aa.txt");
// 读取数据
// int read(byte[] b)从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中
// 读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回 -1
byte[] bytes = new byte[1024];
int num = fileInputStream.read(bytes);
System.out.println("从文件中读取的数据个数:" + num); // 从文件中读取的数据个数:16
// 遍历数组,看文件中读取的数据是哪些
/*for (int i = 0; i < bytes.length; i++) { i不再是小于数据长度
遍历数组,数组里有内容的是下标0-6,在这里遍历所有元素,下标为7及之后的都为空,遍历只需要遍历读取到的数据
}*/
for (int i = 0; i < num; i++) {
System.out.print((char) bytes[i] + " "); // a b c d e f g h i g k l m n o p
}
// 关闭流
fileInputStream.close();
}
}
2、FileOutputStream类(OutputStream类的子类)
构造方法
FileOutputStream(File file) | 创建一个向指定 File 对象表示的文件中写入数据的文件输出流 |
FileOutputStream(File file, boolean append) | 创建一个向指定 File 对象表示的文件中写入数据的文件输出流 |
FileOutputStream(String name) | 创建一个向具有指定名称的文件中写入数据的输出文件流 |
FileOutputStream(String name, boolean append) | 创建一个向具有指定 name 的文件中写入数据的输出文件流 |
常用方法
void write(byte[] b) | 将 b.length 个字节从指定 byte 数组写入此文件输出流中 |
void write(byte[] b, int off, int len) | 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流 |
void write(int b) | 将指定字节写入此文件输出流 |
package javaapidemo0130.demo03;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamDemo01 {
public static void main(String[] args) {
// 创建FileOutputStream类对象
FileOutputStream fileOutputStream = null;
File file = new File("D:/Java2408/FileOutputStreamTest/a.txt");
try {
// FileOutputStream(File file)和FileOutputStream(String path)构造
// 在写入数据时,写入的数据会覆盖文件中已经存在的数据
fileOutputStream = new FileOutputStream(file);
// 通过fileOutputStream对象调用方法将数据写入到指定文件中
fileOutputStream.write(65);
System.out.println("数据写入完毕");
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
package javaapidemo0130.demo03;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamDemo02 {
public static void main(String[] args) {
// 创建FileOutputStream类对象
FileOutputStream fileOutputStream = null;
try {
// FileOutputStream(String path,boolean flag)和FileOutputStream(File file,boolean flag)构造方法中的第二个参数用来标识写入的内容是否覆盖文件中原来已经存在的数据
// 写false或者不写,都表示覆盖内容,如果写true,写入的内容写入到文件的末尾
fileOutputStream = new FileOutputStream("D:/Java2408/FileOutputStreamTest/b.txt", true);
// 通过fileOutputStream对象调用方法向指定文件中写入数据
fileOutputStream.write(66);
System.out.println("数据写入完毕");
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
package javaapidemo0130.demo03;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamDemo03 {
public static void main(String[] args) throws IOException {
// 创建FileOutputStream实例时,如果相应的文件并不存在,则会自动创建一个空的文件
FileOutputStream fileOutputStream = new FileOutputStream("D:/Java2408/FileOutputStreamTest/c.txt");
// 向指定文件中写入数据abcdefg
String str = "abcdefg";
// 将字符串转换成byte类型的数据
byte[] bytes = str.getBytes();
fileOutputStream.write(bytes);
System.out.println("数据写入完毕");
}
}
练习
package javaapidemo0130.demo04;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class InputAndOutputDemo01 {
public static void main(String[] args) {
// 将E盘下面student.txt文件中的内容复制到D盘Java2408目录下的worker.txt文件中
// 创建FileInputStream类对象
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
fileInputStream = new FileInputStream("E:/student.txt");
fileOutputStream = new FileOutputStream("D:/Java2408/worker.txt");
// 通过循环的方式将文件中的数据一个一个的读取出来,读取出来后将数据写入到文件中
int num;
while ((num = fileInputStream.read()) != -1) {
// 不需要将读取的数据输出,直接再写入文件中
fileOutputStream.write(num);
}
System.out.println("文件复制完毕");
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
// 如果一个文件中涉及多个流,在关闭的时候是有顺序的:先开的流后关,后开的流先关
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
一、InputStreamReader类(Reader类的子类)
1、构造方法
InputStreamReader(InputStream in) | 创建一个使用默认字符集InputStreamReader |
InputStreamReader(InputStream in,String charsetName) | 创建使用指定字符集的 InputStreamReader |
2、常用方法
int read() | 读取字符 |
int read(char[] cbuf) | 将字符读入数组 |
int read(char[] cbuf, int offset, int length) | 将字符读入数组中的某一部分 |
package javaapidemo0130.demo05;
import java.io.*;
public class InputStreamReaderDemo01 {
public static void main(String[] args) {
// 创建InputStreamReader类对象
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
try {
inputStream = new FileInputStream("D:/Java2408/InputStreamReader/a.txt");
// InputStreamReader(InputStream in):创建一个使用默认字符集的 InputStreamReader。
// InputStreamReader(InputStream in, String charsetName):创建使用指定字符集的 InputStreamReader
inputStreamReader = new InputStreamReader(inputStream);
// inputStreamReader = new InputStreamReader(inputStream,"GBK"); // 使用指定字符编码
// 通过inputStreamReader对象调用方法读取数据
// int num = inputStreamReader.read();
int num;
while ((num = inputStreamReader.read()) != -1) {
System.out.print((char) num); // abcdefg
// 如果文件内容有中文,可能出现乱码的情况
// IDEA编码格式与文件编码格式一致,则不会乱码
// System.out.println(System.getProperty("file.encoding"));获得本地平台的字符编码类型
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
// IDEA平台编码
System.out.println(System.getProperty("file.encoding")); // UTF-8
}
}
package javaapidemo0130.demo05;
import java.io.*;
public class InputStreamReaderDemo02 {
public static void main(String[] args) {
File file = new File("D:/Java2408/InputStreamReader/b.txt");
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
try {
inputStream = new FileInputStream(file);
inputStreamReader = new InputStreamReader(inputStream, "GBK");
// 读取数据,并将读取到的数据存储在char类型数组中
char[] chars = new char[1024];
int num = inputStreamReader.read(chars);
// 遍历数组,输出数组中读取到的数据
for (int i = 0; i < num; i++) {
System.out.print(chars[i]); // abcdefg鏂板勾蹇箰
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (inputStreamReader != null) {
try {
inputStreamReader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
二、FileReader类(InputStreamReader类的子类)
1、构造方法
FileReader(File file) | 在给定从中读取数据的 File 的情况下创建一个新 FileReader |
FileReader(String fileName) | 在给定从中读取数据的文件名的情况下创建一个新 FileReader |
2、常用方法
int read() | 读取字符 |
int read(char[] cbuf) | 将字符读入数组 |
int read(char[] cbuf, int offset, int length) | 将字符读入数组中的某一部分 |
package javaapidemo0130.demo06;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo01 {
public static void main(String[] args) {
// 创建FileReader类对象
FileReader fileReader = null;
try {
// FileReader类只能按照平台的编码格式去读取文件中的数据,不能指定编码格式
fileReader = new FileReader("D:\\Java2408\\FileReader\\b.txt"); // 文件内容abcdefg新年快乐
// 通过fileReader对象调用方法读取数据
// int num =fileReader.read();
// System.out.println((char)num);
int num;
while ((num = fileReader.read()) != -1) {
System.out.print((char) num); // abcdefg新年快乐
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
三、BufferedReader类(Reader类的子类)
如何提高字符流读取文本文件的效率?使用FileReader类与BufferedReader类
BufferedReader类是Reader类的子类;BufferedReader类带有缓冲区;按行读取内容的readLine()方法
1、构造方法
BufferedReader(Reader in) | 创建一个使用默认大小输入缓冲区的缓冲字符输入流 |
2、常用方法
int read() | 读取单个字符 |
int read(char[] cbuf, int off, int len) | 将字符读入数组的某一部分 |
String readLine() | 读取一个文本行 |
package javaapidemo0130.demo07;
import java.io.*;
public class BufferedReaderDemo01 {
public static void main(String[] args) {
// 创建BufferedReader类对象
File file = new File("D:/Java2408/BufferedReader/b.txt");
InputStream inputStream = null;
Reader reader = null;
BufferedReader bufferedReader = null;
try {
inputStream = new FileInputStream(file);
reader = new InputStreamReader(inputStream, "UTF-8");
bufferedReader = new BufferedReader(reader);
// 通过bufferedReader对象读取数据
// int num =bufferedReader.read();
// System.out.println((char)num);
//一行一行的读取数据
/*
String str1 =bufferedReader.readLine();
System.out.println(str1);
String str2 =bufferedReader.readLine();
System.out.println(str2);
String str3 =bufferedReader.readLine();
System.out.println(str3);
String str4 =bufferedReader.readLine();
System.out.println(str4);
String str5 =bufferedReader.readLine();
System.out.println(str5);
String str6 =bufferedReader.readLine();
System.out.println(str6);
上面的操作可以使用循环的方式来读取,只要读取的数据不为null,说明数据没有读取完,可以一直读
while(bufferedReader.readLine()!=null){
String str =bufferedReader.readLine();
System.out.println(str);
}
*/
// 上面的读取操作会出现隔一行读一行,因为调用了2次readLine()方法,第一次判断读取的结果是否为null,第二次读取数据,我们需要读取数据后只要数据不为null,就输出
String str;
while ((str = bufferedReader.readLine()) != null) {
System.out.println(str);
// abcdefg
// 新年快乐
// 恭喜发财
// 顺风顺水
// 万事如意
// asdfg
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
四、OutputStreamWriter类(Writer类的子类)
1、构造方法
OutputStreamWriter(OutputStream out) | 创建使用默认字符编码的 OutputStreamWriter |
OutputStreamWriter(OutputStream out,String charsetName) | 创建使用指定字符集的 OutputStreamWriter |
2、常用方法
void write(char[] cbuf) | 写入字符数组 |
void write(char[] cbuf,int off,int len) | 写入字符数组一部分 |
void write(int c) | 写入单个字符 |
void write(String str) | 写入字符串 |
void write(String str,int off,int len) | 写入字符串的一部分 |
void flush() | 刷新该流的缓冲 |
package javaapidemo0131.demo08;
import java.io.*;
public class OutputStreamWriterDemo01 {
public static void main(String[] args) {
//创建OutPutStreamWriter类对象
OutputStream outputStream = null;
OutputStreamWriter outputStreamWriter = null;
try {
outputStream = new FileOutputStream("D:/Java2408/OutputStreamWriter/a.txt", true);
outputStreamWriter = new OutputStreamWriter(outputStream);
//通过outputStreamWriter对象调用方法将数据写入到指定文件中
// outputStreamWriter.write(65);
// outputStreamWriter.write("qwertyuiop");
outputStreamWriter.write("asdfghjkl", 1, 3);
//此时数据还没有写入到文件中,因为数据还在缓冲中,需要使用方法将数据从缓冲里面传入到文件中
outputStreamWriter.flush();
System.out.println("数据写入完毕");
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
//多个流,后开的先关,先开的后关
if (outputStreamWriter != null) {
try {
outputStreamWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
五、FileWriter类(OutputStreamWriter的子类)
1、构造方法
FileWriter(File file) | 根据给定的 File 对象构造一个 FileWriter 对象 |
FileWriter(File file,boolean append) | 根据给定的 File 对象构造一个 FileWriter 对象 |
FileWriter(FileDescriptor fd) | 构造与某个文件描述符相关联的 FileWriter 对象 |
FileWriter(String fileName) | 根据给定的文件名构造一个 FileWriter 对象 |
FileWriter(String fileName,boolean append) | 根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象 |
2、常用方法
void write(char[] cbuf) | 写入字符数组 |
void write(char[] cbuf,int off,int len) | 写入字符数组一部分 |
void write(int c) | 写入单个字符 |
void write(String str) | 写入字符串 |
void write(String str,int off,int len) | 写入字符串的一部分 |
void flush() | 刷新该流的缓冲 |
package javaapidemo0131.demo09;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo01 {
public static void main(String[] args) {
// 创建FileWriter类对象
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter("D:/Java2408/FileWriter/a.txt", true);
// 通过fileWriter对象调用方法将数据写入到文件中
char[] chars = {'J', 'a', 'v', 'a', '2', '4', '0', '8'};
fileWriter.write(chars);
// 将缓冲中的数据刷新到文件中
fileWriter.flush();
System.out.println("数据写入完毕");
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (fileWriter != null) {
try {
fileWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
六、BufferedWriter类(Writer类的子类)
如何提高字符流写文本文件的效率?使用FileWriter类与BufferedWriter类
BufferedWriter类是Writer类的子类;BufferedWriter类带有缓冲区
1、构造方法
BufferedWriter(Writer out) | 创建一个使用默认大小输出缓冲区的缓冲字符输出流 |
2、常用方法
void newLine() | 写入一个行分隔符 |
void write(char[] cbuf) | 写入字符数组 |
void write(char[] cbuf,int off,int len) | 写入字符数组一部分 |
void write(int c) | 写入单个字符 |
void write(String str) | 写入字符串 |
void write(String str,int off,int len) | 写入字符串的一部分 |
package javaapidemo0131.demo10;
import java.io.*;
public class BufferedWriterDemo01 {
public static void main(String[] args) {
// 创建BufferedWriter类对象
OutputStream outputStream = null;
Writer writer = null;
BufferedWriter bufferedWriter = null;
try {
outputStream = new FileOutputStream("D:/Java2408/BufferedWriter/a.txt", true);
writer = new OutputStreamWriter(outputStream, "UTF-8");
bufferedWriter = new BufferedWriter(writer);
// 通过bufferedWriter对象调用方法将数据写入指定文件中
bufferedWriter.write("Java从入门到精通");
bufferedWriter.write("Java从入门到放弃");
// 写入一个换行分隔符
bufferedWriter.newLine();
bufferedWriter.write("Java从入门到精神病康复指南");
bufferedWriter.newLine();
bufferedWriter.write("Java是世界上最好的语言");
bufferedWriter.flush();
System.out.println("数据写入成功");
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (bufferedWriter != null) {
try {
bufferedWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
七、练习替换文件中的内容
package javaapidemo0131.demo11;
import java.io.*;
public class Demo01 {
public static void main(String[] args) {
// 先将pet.txt文件中的数据读取出来
InputStream inputStream = null;
Reader reader = null;
BufferedReader bufferedReader = null;
OutputStream outputStream = null;
Writer writer = null;
BufferedWriter bufferedWriter = null;
try {
inputStream = new FileInputStream("D:/Java2408/Replace/pet.txt");
reader = new InputStreamReader(inputStream, "UTF-8");
bufferedReader = new BufferedReader(reader);
// 读取数据
String str = bufferedReader.readLine();
// 输出读取到的你内容
System.out.println("替换前:" + str);
String s1 = str.replace("{name}", "欧欧").replace("{type}", "狗狗").replace("{master}", "李伟");
System.out.println("替换后:" + s1);
// 将替换好的字符串s1重新写入到pet.txt文件中
outputStream = new FileOutputStream("D:/Java2408/Replace/pet.txt");
writer = new OutputStreamWriter(outputStream, "UTF-8");
bufferedWriter = new BufferedWriter(writer);
// 将数据写入文件
bufferedWriter.write(s1);
bufferedWriter.flush();
System.out.println("数据写入完毕");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (bufferedWriter != null) {
try {
bufferedWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
八、读写二进制文件
1、DataInputStream类(FilterInputStream的子类)
与FileInputStream类结合使用读取二进制文件
1)构造方法
DataInputStream(InputStream in) | 使用指定的底层 InputStream 创建一个 DataInputStream |
2)常用方法
int read() | 读取单个字节 |
int read(byte[] b) | 从包含的输入流中读取一定数量的字节,并将它们存储到缓冲区数组 b 中 |
int read(byte[] b, int off, int len) | 从包含的输入流中将最多 len 个字节读入一个 byte 数组中 |
2、DataOutputStream类(FilterOutputStream的子类)
与FileOutputStream类结合使用写二进制文件
1)构造方法
DataInputStream(OutputStream out) | 创建一个新的数据输出流,将数据写入指定基础输出流 |
2)常用方法
void write(int b) | 将b.length个字节写入此输出流 |
void write(byte[] b) | 将指定字节(参数 b 的八个低位)写入基础输出流;将b.length个字节从指定byte数组写入此文件输出流中 |
void write(byte[] b,int off,int len) | 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入基础输出流 |
package javaapidemo0131.demo12;
import java.io.*;
public class DataInputStreamAndDataOutputStreamDemo01 {
public static void main(String[] args) {
// 创建DataInputStream类对象
InputStream inputStream = null;
DataInputStream dataInputStream = null;
OutputStream outputStream = null;
DataOutputStream dataOutputStream = null;
try {
inputStream = new FileInputStream("D:/Java2408/Data/Car.jpg");
dataInputStream = new DataInputStream(inputStream);
// 创建二进制输出流
outputStream = new FileOutputStream("D:/Java2408/Data/newCar.jpg");
dataOutputStream = new DataOutputStream(outputStream);
// 读取数据
int num;
while ((num = dataInputStream.read()) != -1) {
// System.out.print(num+" ");
// 读取到的是图片转换成的二进制数字(二进制数字转换成了十进制数字),输出没有意义,可以将读取到的数据再写入到另一个图片文件中
// 将读取到的数据写入到指定文件中
dataOutputStream.write(num);
}
System.out.println("图片复制完毕");
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
九、序列化和反序列化
1、概念
序列化是将对象的状态写入到特定的流中的过程
反序列化则是从特定的流中获取数据重新构建对象的过程
2、ObjectOutputStream(OutputStream类的子类)
1)构造方法
ObjectOutputStream(OutputStream out) | 创建写入指定 OutputStream 的 ObjectOutputStream |
2)常用方法
void writeObject(object obj) | 将指定的对象写入ObjectOutputStream |
3、ObjectInputStream(InputStream类的子类)
1)构造方法
ObjectInputStream(InputStream in) | 创建从指定InputStream读取的ObjectInputStream |
2)常用方法
Object readObject() | 从 ObjectInputStream 读取对象 |
package javaapidemo0131.demo13;
import java.io.Serializable;
public class Student implements Serializable {
private String name;
private int age;
private char gender;
public Student() {
}
public Student(String name, int age, char gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
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 char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", gender=" + gender +
'}';
}
}
package javaapidemo0131.demo13;
import java.io.*;
public class ObjectOutputStreamDemo01 {
public static void main(String[] args) {
// 创建一个Student类对象
Student student = new Student("张三", 20, '男');
// 将student对象写入到指定文件中
// 创建ObjectOutputStream类对象
OutputStream outputStream = null;
ObjectOutputStream objectOutputStream = null;
try {
outputStream = new FileOutputStream("D:\\Java2408\\Object\\student.txt");
objectOutputStream = new ObjectOutputStream(outputStream);
// 通过objectOutputStream对象调用方法将student对象写入到指定文件中
objectOutputStream.writeObject(student);
System.out.println("对象写入完毕");
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (objectOutputStream != null) {
try {
objectOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
/*
Exception in thread "main" java.lang.RuntimeException: java.io.NotSerializableException: javaapidemo0131.demo13.Student
at javaapidemo0131.demo13.ObjectOutputStreamDemo01.main(ObjectOutputStreamDemo01.java:27)
Caused by: java.io.NotSerializableException: javaapidemo0131.demo13.Student
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at javaapidemo0131.demo13.ObjectOutputStreamDemo01.main(ObjectOutputStreamDemo01.java:21)
*/
/*
报异常:没有序列化
对象所在的类需要接口实现序列化
public interface Serializable类通过实现 java.io.Serializable 接口以启用其序列化功能
public class Student implements Serializable {} // 对象写入完毕
*/
package javaapidemo0131.demo13;
import java.io.*;
public class ObjectInputStreamDemo01 {
public static void main(String[] args) {
// 读取D盘中Java2408目录下student.txt文件中的对象信息
// 创建ObjectInputStream类对象
InputStream inputStream = null;
ObjectInputStream objectInputStream = null;
try {
inputStream = new FileInputStream("D:/Java2408/Object/student.txt");
objectInputStream = new ObjectInputStream(inputStream);
// 通过objectInputStream对象调用方法从指定文件中读取对象信息
Object object = objectInputStream.readObject();
// 将object对象转换为其真实类型Student
Student student = (Student) object;
System.out.println(student); // Student{name='张三', age=20, gender=男}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} finally {
if (objectInputStream != null) {
try {
objectInputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
创建多个对象存储在数组中
package javaapidemo0131.demo13;
import java.io.*;
public class ObjectOutputStreamDemo02 {
public static void main(String[] args) {
// 创建3个Student对象
Student student1 = new Student("张三", 22, '男');
Student student2 = new Student("李四", 25, '男');
Student student3 = new Student("王五", 29, '男');
// 将这个三个Student类对象存储到数组或者集合中
Student[] students = {student1, student2, student3};
// 创建ObjectOutputStream类对象
OutputStream outputStream = null;
ObjectOutputStream objectOutputStream = null;
try {
outputStream = new FileOutputStream("D:/Java2408/Object/students.txt");
objectOutputStream = new ObjectOutputStream(outputStream);
// 写入数据
objectOutputStream.writeObject(students);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (objectOutputStream != null) {
try {
objectOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
package javaapidemo0131.demo13;
import java.io.*;
import java.util.Arrays;
public class ObjectInputStreamDemo02 {
public static void main(String[] args) {
// 读取D盘中Java2408目录下student.txt文件中的对象信息
// 创建ObjectInputStream类对象
InputStream inputStream = null;
ObjectInputStream objectInputStream = null;
try {
inputStream = new FileInputStream("D:/Java2408/Object/students.txt");
objectInputStream = new ObjectInputStream(inputStream);
// 通过objectInputStream对象调用方法从指定文件中读取对象信息
Object object = objectInputStream.readObject();
// 将object对象转换为其真实类型Student类型的数组
Student[] students = (Student[]) object;
// 遍历数组students
System.out.println(Arrays.toString(students));
// [Student{name='张三', age=22, gender=男}, Student{name='李四', age=25, gender=男}, Student{name='王五', age=29, gender=男}]
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} finally {
if (objectInputStream != null) {
try {
objectInputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
4、transient隐藏序列化信息
package javaapidemo0131.demo13;
import java.io.Serializable;
public class Worker implements Serializable {
private String name;
// 如果类中某个属性不想被序列化操作,可以使用transient进行修饰
private transient int age;
private char gender;
public Worker() {
}
public Worker(String name, int age, char gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
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 char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Worker{" +
"name='" + name + '\'' +
", age=" + age +
", gender=" + gender +
'}';
}
}
package javaapidemo0131.demo13;
import java.io.*;
public class WorkerObjectOutputStreamDemo01 {
public static void main(String[] args) {
// 创建一个Worker类对象
Worker worker = new Worker("张三", 22, '男');
// 将worker对象写入到指定文件中
// 创建ObjectOutputStream类对象
OutputStream outputStream = null;
ObjectOutputStream objectOutputStream = null;
try {
outputStream = new FileOutputStream("D:\\Java2408\\Object\\worker.txt");
objectOutputStream = new ObjectOutputStream(outputStream);
// 通过objectOutputStream对象调用方法将worker对象写入到指定文件中
objectOutputStream.writeObject(worker);
System.out.println("对象写入完毕");
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (objectOutputStream != null) {
try {
objectOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
package javaapidemo0131.demo13;
import java.io.*;
public class WorkerObjectInputStreamDemo01 {
public static void main(String[] args) {
// 读取F盘中Java2408目录下student.txt文件中的对象信息
// 创建ObjectInputStream类对象
InputStream inputStream = null;
ObjectInputStream objectInputStream = null;
try {
inputStream = new FileInputStream("D:/Java2408/Object/worker.txt");
objectInputStream = new ObjectInputStream(inputStream);
// 通过objectInputStream对象调用方法从指定文件中读取对象信息
Object object = objectInputStream.readObject();
// 将object对象转换为其真实类型Worker
Worker worker = (Worker) object;
System.out.println(worker); // Worker{name='张三', age=0, gender=男}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} finally {
if (objectInputStream != null) {
try {
objectInputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}