Java I/O(input/output)
文件 | 内存 | 键盘
—> 程序
的过程叫做
读
程序 —>
文件 | 内存 | 控制台的过程叫做
写
文件(File类)
相关记录或放在一起的数据的集合叫做文件
通过Java.io.File类访问文件属性
1
2
3
4
5
6
7
|
/*
*创建文件对象语法
*参数内(path name(路径名称))为文件的目录
*如"c:\\test.txt"或"c:/test.txt"
*"\"为转义符所以需再转义
*/
File file =
new
File(String pathname);
|
File类的常用方法
方法名称
|
说明
|
boolean exists()
|
判断文件或目录是否存在
|
boolean isFile()
|
判断是否是文件
|
boolean isDirectory()
|
判断是否是目录
|
String getPath()
|
返回此对象表示的文件的相对路径名
|
String getAbsolutePath()
|
返回此对象表示的文件的绝对路径名
|
String getName()
|
返回此对象表示的文件或目录的名称
|
boolean delete()
|
删除此对象制定的文件或目录
|
boolean createNewFile()
|
创建名称的空文件,不能创建文件夹
|
long length()
|
返回文件的长度,单位为字节,如果文件不存在,则返回0L
|
*相对路径:当前的位置继续向下的路径
*绝对路径:从根目录(如:C:\)向下的路径
1汉字字符=2字节
1英文字符=1字节
知识点:流
- 通过流来读写文件
- 流是一组有序的数据序列
- 以先进先出方式发送信息的通道
- 文件 | 内存 | 键盘 —> 程序的过程叫做读
- 程序 —> 文件 | 内存 | 控制台的过程叫做写
- 关闭流时按照后创建的先关闭的顺序关闭
- 流的分类
- 按流向区分
- 输出流
- OutputStream和Writer作为父类
- 输入流
- InputStream和Reader作为父类
- 输出流
- 按流向区分
*输入输出流是相对于计算机内存来说的
-
- 按照处理数据单元划分
- 字节流
- 字节输入流InputStream作为父类
- 字节输出流OutputStream作为父类
- 字符流
- 字符输入流Reader作为父类
- 字符输出流Writer作为父类
- 字节流
- 按照处理数据单元划分
*字节流是8位通用字节流,字符流是16为Unicode字符流
————————————————————————————————
1.1输入流(InputStream&Reder)
用来读数据
InputStream&Reder都是抽象父类
1.1.1字节输入流(
InputStream抽象类
—>
FileInputStream子类
)
通过父类类型指向子类对象创建
-
-
- InputStream类常用方法
- int read():从输入流一个字节一个字节的读,返回该字节的整数表示形式,如果到了末位,返回-1
- int read(byte[] b):从输入流读取若干个字节,把这些字节保存到数组b中,返回的是读取到的字节数,如果到了末位,返回-1
- int read(byte[] b,int off,int len):从输入流读取若干个字节,把这些字节保存到数组b中,off指的是字节数组中开始保存数据的起始下标,len指的是想读取的字节数,返回的是读取到的字节数,如果到了末位,返回-1
- void close():关闭流
- int available():可以从输入流中读取的字节数目
- 子类FileInputStream常用的构造方法
- FileInputStream(File file):参数为文件类对象
- FileInputStream(String name):参数为路径
- InputStream类常用方法
-
//创建父类类型
InputStream is = null;
try {
//创建输入流对象:父类类型指向子类对象
is = new FileInputStream("C:\\Users\\Administrator\\Desktop\\first.txt");
//创建byte数组,空间为文件中未读取的字节数
byte[] b = new byte[is.available()];
//读取文件,每一个字节保存在byte数组中
is.read(b);
//遍历byte数组并打印其中内容,需转换为char输出
for(byte a : b){
System.out.print((char)a);
}
}catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}finally{
try{
//关闭流,无论程序是否发生异常都会运行
is.close();
}catch (IOException e) {
e.printStackTrace();
}
}
————————————————————————————————
1.1.2字符输入流(
Rader抽象类
—>
InputStreamRader子类 —> FileReader孙子类
)
通过父类类型指向子类对象创建
- Reader类常用方法
- int read()
- int read(char[] c]
- read(char[]c , int off , int len)
- void colse()
- 子类InputStreamReader常用的构造方法
- InputStreamReader(InputStream in)
- InputStreamReader(InputStream in,String charsetName):第二个参数可以指定读取的编码格式
- 孙子类FileReader
- FileReader类是InputStreamReader类的子类
- 构造方法
- FileReader(File file)
- FileReader(String name)
- 该类只能按照本地平台的字符编码来读取数据,用户不能指定其他的字符编码类型
- System.out.println(System.getProperty("file.encoding"));获得本地平台的字符编码类型
- 中文出现乱码:
- 原因:文件编码格式和程序环境的编码格式不一致
- 解决方法:字符流去读的时候,指定字符流的编码格式
- FileReader无法指定编码格式,按照系统默认的编码格式读取
- *使用InputStreamReader,该类可以指定编码格式
//读取文件产生乱码时解决方法
//查看本地平台的字符编码格式
System.out.println(System.getProperty("file.encoding"));
//创建FileInputStream和Reader类型
FileInputStream fis = null;
Reader fr = null;
//捕获异常
try {
/*
* 文件读取出现乱码:文件编码格式和程序环境的编码格式不一致
*/
// Reader read = newFileReader("C:\\Users\\Administrator\\Desktop\\测试.txt");
// int i = read.read();
// while(i != -1){
// System.out.println((char)i);
// i = read.read();
// }
/*
* 使用InputStreamReader指定编码格式输入文件
*/
//实例化fis和fr对象
fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\测试.txt");
fr = new InputStreamReader(fis,"UTF-8");
//读取文件并打印内容
int i1 = fr.read();;
while(i1 !=-1){
System.out.print((char)i1);
i1 = fr.read();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
1.1.3缓冲流BufferedReader
为了提高读取文本文件的效率,可以使用FileReader类与BufferedReader类
BufferedReader可以
包装Reader的子类
- BufferedReader类是Reader类的子类
- BufferedReader类带有缓冲区
- 按行读取内容的readLine()方法
————————————————————————————————
1.2输出流(OutputStream&Writer)
用来写数据
OutputStream&Writer都是抽象父类
1.2.1字节输出流(
OutputStream抽象类
—>
FileOutputStream子类
)
通过父类类型指向子类对象创建
-
-
- OutputStream类常用方法
- void write(int c):写一个字节
- void write(byte[] buf):写一个字节数组
- void write(byte[] b,int off,int len):写一个字节数组,从哪里开始写,写多长
- void close():关闭流
- void flush():强制把缓冲区的数据写到输出流中
- 子类FileOutputStream常用的构造方法
- FileOutputStream(File file):参数为文件类对象
- FileOutputStream(String name):参数为路径
- FileOutputStream(String name,boolean append):第一个参数为路径,第二个参数判断是否在源文件的内容上追加内容,true追加,false不追加,默认不追加
————————————————————————————————//创建父类类型 OutputStream os = null; try { //创建输出流对象:父类类型指向子类对象 os = new FileOutputStream("C:/Users/Administrator/Desktop/first.txt"); //要写入的字符串:Hello World String str = "Hello World!"; //将字符串转化为byte字节数组 byte[] tybes = str.getBytes(); //将tybes数组写入路径中的文件 os.write(tybes); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ try { //清空缓冲区 os.flush(); //关闭流 os.close(); } catch (IOException e) { e.printStackTrace(); } }
- OutputStream类常用方法
-
1.2.2字符输出流(
Writer抽象类
—>
OutputStreamWriter子类
)
通过父类类型指向子类对象创建
- Writer类常用方法
- Write(String str)
- write(String str , int off , int len)
- void close():关闭流
- void flush():清空缓冲区
- 子类OutputStreamWriter常用的构造方法
- OutputStreamWriter(OutputStream out)
- OutputStreamWriter(OutputStream out , String charsetName)
- 孙子类FileStreamWtiter
- FileStreamWtiter是OutputStreamWriter的子类
- 构造方法(以下两种构造方法,都可以重载,可以指定一个boolean类型的参数,用来指定追加还是覆盖文件内容)
- FileStreamWtiter(File File)
- FileStreamWtiter(String path)
————————————————————————————————/* * 输出流 */ //声明父类类型 Writer fw = null; //捕获异常 try { //实例化子类对象:(路径,追加or覆盖) true:追加 false:覆盖 fw = new FileWriter("C:\\Users\\Administrator\\Desktop\\测试.txt",true); //需要输出的字符串 String info = "输入和输出处理最后一部分内容"; //输出方法 fw.write(info); //清空缓冲区方法 fw.flush(); } catch (IOException e) { e.printStackTrace(); }finally{ try { //关闭流 fw.close(); } catch (IOException e) { e.printStackTrace(); } }
1.1.3缓冲流BufferedWriter
为了提高读取文本文件的效率,可以使用FileWriter类与BufferedWriter类
BufferedWriter可以
包装Writer的子类
- BufferedWriter类是Writer类的子类
- BufferedWriter类带有缓冲区
- BufferedWriter类常用的构造方法
- BufferedWriter(Writer out)
————————————————————————————————
1.3读写二进制文件
- DataInputStream类
- FileInputStream的子类
- 与FileInputStream类结合使用读取二进制文件
- DateOutputStream类
- FileOutputStream的子类
- 与FileOutputStream类结合使用写二进制文件
————————————————————————————————/* * 拷贝二进制文件:图片、音频文件、视频文件等 */ //声明父类类型:读取 DataInputStream dis = null; FileInputStream fis = null; //声明父类类型:输出 DataOutputStream dos = null; FileOutputStream fos = null; //捕获异常 try { //输入流:读取文件 fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\Fate素描.jpg"); dis = new DataInputStream(fis); byte[] b = new byte[fis.available()]; dis.read(b); //输出流:输出文件 fos = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\Fate素描(2).jpg"); dos = new DataOutputStream(fos); fos.write(b); dos.close(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ try { dos.close(); fos.close(); dis.close(); fis.close(); } catch (IOException e) { e.printStackTrace(); } }
1.4序列化和反序列化
-
- 序列化
- Java对象(内存) ——> 二进制的字节序列(流)
- *序列化是将对象的状态写入到特定的流中的过程
- 反序列化
- 二进制的字节序列(流) ——> Java对象(内存)
- *反序列化是从特定的流中获取数据重新构建对象的过程
- 序列化
-
- 常见异常:
- NotSerializableExcaption:类没有实现Serializable接口,不可被序列化
- 序列化的步骤(ObjectOutputStream)
- 实现Serializable接口
- 创建对象输出流
- 调用writeObject()方法将对象写入文件
- 关闭对象输出流
- 常见异常:
- 反序列化的步骤(ObjectInputStream)
- 实现Serializable接口
- 创建对象输入流
- 调用readerObject()方法读取文件中的对象
- 关闭对象输出流
***关键字transient:修饰字段后,屏蔽该字段,该字段不会被序列化或反序列化
//学生类:实现序列化接口
class StudentTest implements Serializable{
public String name;
public StudentTest(String name) {
this.name = name;
}
}
//测试类
public class Test4 {
public static void main(String[] args) {
//创建学生对象
StudentTest stu = new StudentTest("张三");
/*
* 序列化
*/
//声明对象输出类型
ObjectOutputStream oos = null;
FileOutputStream fos = null;
//捕捉异常
try {
//创建对象输出对象
fos = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\测试.txt");
oos = new ObjectOutputStream(fos);
//输出学生对象
oos.writeObject(stu);
//清空缓冲区
oos.flush();
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
//关闭流
oos.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/*
* 反序列化
*/
//声明对象输入类型
ObjectInputStream ois = null;
FileInputStream fis = null;
//捕捉异常
try {
//创建对象输入对象
fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\测试.txt");
ois = new ObjectInputStream(fis);
//输入学生对象
StudentTest stu1 = (StudentTest) ois.readObject();
//打印学生对象信息
System.out.println("反序列化后的信息:"+stu1.name);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
//关闭流
ois.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}