1、什么是java io?
Java IO即Java 输入输出系统。IO
:Input/Output即输入&输出,也称之为流(河流,水流),指的是数据从一个地点到另一个地点过程;对于计算机来说文件的拷贝过程,文件的编写保存,显示功能都是使用到IO;将数据的传输过程看做一个输入输出。
-
输入输出介质
- 文件
- 网络
- 键盘(输入)
- 显示器(输出)
2、File类
什么是File?
一个文件类的对象可以代表一个文件或者目录,可获取与文件相关的信息,如名称,修改日期,文件大小等,
语法:public File(String pathName)
- 绝对路径:以跟目录开头的完整路径
- 相对路径:以对应当前目录文件的路径
- "."表示当前目录
- ".."表示上级目录
示例:File file = new File("C:\\test.txt"); 创建File对象的时,必须设置文件路径
java程序如何访问文件?
Java API:java.io.File 类
File类的常用方法
方法名 | 描述 |
boolean createNewFile() | 创建新文件 |
boolean delete() | 删除文件 |
boolean exists() | 判断文件是否存在 |
Boolean isFile() | 判断是否是文件 |
boolean isDirectory() | 判断是否是目录 |
long length() | 返回文件长度,单位为字节 若文件不存在,则返回0L |
String getPath() | 返回此对象文件名所对应的路径 |
String getAbsolutePath() | 返回此对象表示的文件的绝对路径名 |
3、流
流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或者是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。这时候你就可以想象数据好像在这其中“流”动一样。
Java把这些不同来源和目标的数据都统一抽象为数据流。
分类
按流向分:
1)输入流:程序可以从中读取数据的流;
2)输出流:程序能向其中写入数据的流
按数据传输单位分:
1)字节流:以字节为单位传输数据的流;
2)字符流:以字符为单位传输数据的流;
按功能分:
1)节点流:用于直接操作目标设备的流;
2)过滤流:是对一个已存在的流的链接和封装,通过对数据进行处理为程序提供功能强大、灵活的读写功能。
字节流 | 字符流 | |
输出流 | InputStream | Reader |
输入流 | OutputStream | Writer |
3.1字节流IO常用方法(数据单位为1字节(8Bit))
(1)InputStream:字节输入流
常用方法(2个):
int read(); 读取一个字节的数据到程序中,数据类型是int(0~255之间的一个数),如果没有读到数据会返回-1(输入完毕)。如果读到的是字符则返回对应的ASCII码。
void close(); 关闭输入流对象,释放相关资源。
(2)OutputStream:字节输出流
常用方法(2个):
void write( int n ); 向目的地写入一个字节 int(0~255之间的一个数),没有返回值。
void close(); 关闭输出流对象,释放相关资源。
3.2字符流IO常用方法(编码是Unicode,2或4字节)
(1)Reader:字符输入流
常用方法(2个):
int read(); 读取一个字符的数据到程序中,数据类型是int(0~65535之间的一个数,即Unicode值),如果没有读到数据会返回-1(输入完毕)。
void close(); 关闭输入流对象,释放相关资源。
(1)Writer:字符输出流
常用方法(2个):
void write(int n); 向目的地写入一个字节 int(0~65535之间的一个数),没有返回值。
void close(); 关闭输出流对象,释放相关资源。
4、Java IO的基本用法
1、Java IO:字节流
通过上面我们已经知道,字节流对应的类是InputStream和OutputStream,而在我们实际开发中,我们应该根据不同的媒介类型选用相应的子类来处理。下面我们就用字节流来操作文件媒介:
例1,用字节流输出文件
OutputStream fos = null;
fos = new FileOutputStream("D:\\doc\\test.txt", true);
//准备一个字符串 String str = "I love Java!";
//将字符串转换为byte数组 byte[] words = str.getBytes();
fos.write(words, 0, words.length); System.out.println("文件已写入成功!)
例2,用字节流读文件
fis= new FileInputStream("D:\\doc\\test.txt");
System.out.println("可读取的字节数:"+ fis.available());
int data = 0; System.out.println("文件的内容:");
while((data = fis.read()) != -1) {
System.out.print((char)data + " ");
}
Java IO:字符流
字符流对应的类应该是Reader和Writer。下面我们就用字符流来操作文件媒介
例3,用字符流输出文件
Writer fw = null;
try {
fw = new FileWriter("D:\\doc\\mysaying.txt");
fw.write("预测未来的最好方式就是创造未来!");
fw.flush();//刷新缓冲区
System.out.println("文件写入成功!");
}catch (IOException ex){
}finally {
if(fw!=null){
try {
fw.close();
}catch(IOException ex){
ex.printStackTrace();
}
}
例4,用字符流读文件
Reader fr = null;
try {
fr = new FileReader("D:\\doc\\诗词.txt");
char[] ch = new char[1024];
int len = 0;
while((len = fr.read(ch)) > 0) {
System.out.println(new String(ch,0,len));
}
}catch (FileNotFoundException ex) { //省略异常处理代码
}finally {
fr.close();
}
4.1Java IO:BufferedInputStream和BufferedOutputStream
BufferedInputStream:就是在对流进行写入时提供一个buffer来提高IO效率。在进行磁盘或网络IO时,正常的InputStream对数据读取的过程是一个字节一个字节读取的,而BufferedInputStream在其内部提供了一个buffer,在读数据时,会一次性的读取一大块数据到buffer当中,这样会比单字节的操作快的多,特别是进程磁盘IO和对大量数据进行读写的时候。
例:
public static void main(String[] args) {
File file = new File( "D:/test.txt");
byte[] bytes = new byte[( int) file.Length()];
//可以在构造参数中传入buffer大小
InputStream is = new BufferedInputStream( new FileInputStream(file),2*1024);
int size = is.read(bytes);
System. out.println("大小:" + size + ";内容:" + new String(bytes));
is.close();
}
BufferedOutputStream:与BufferedInputStream同理,只不过一个是输入一个是输出
Java IO:BufferedReader和BufferedWriter
BufferedReader、BufferedWriter 的作用基本和BufferedInputStream、BufferedOutputStream相同,具体用法和原理都差不多 ,只不过一个是面向字符流一个是面向字节流。
例:
public static void main(String[] args){
File file = new File( "D:/test.txt");
// 在字符流基础上用buffer流包装,也可以指定buffer的大小
Reader reader = new BufferedReader( new FileReader(file),2*1024);
char[] bytes = new char[( int) file.length()];
int size = reader.read( bytes);
System. out.println("大小:" + size + ";内容:" + new String(bytes));
reader.close();
5、数据操作流
在IO包中,提供了两个与平台无关的数据操作流,分别是数据输出流( DataOutputStream
) 和数据输入流( Datalnpu tStream
), 通常数据输出流会按照一定的格式将数据输出,再通过数据输入流按照一定的格式将数据读入,这样可以方便地对数据进行处理。
分类
DataOutputStream类 是OutputStream类的子类 与FileOutputStream类结合使用写二进制文件
使用DataOutputStream类写二进制文件的实现步骤与FileOutputStream类写文本文件相似
按照与平台无关的方式向流中写入基本数据类型的数据
例
FileOutputStream out1 = new FileOutputStream("D:\\doc\\test.txt");
BufferedOutputStream out2 = new BufferedOutputStream(out1);
DataOutputStream out = new DataOutputStream(out2);
out.writeByte(1);
out.writeLong(2);
out.writeChar('c');
out.writeUTF("hello");
DataInputStream类 是InputStream类的子类 与FileInputStream类结合使用读取二进制文件
使用DataInputStream类读取二进制文件的实现步骤与FileInputStream类读取文本文件相似
按照与平台无关的方式从流中读取基本数据类型的数据
例
FileInputStream in1 = new FileInputStream("D:\\doc\\test.txt");
BufferedInputStream in2 = new BufferedInputStream(in1);
DataInputStream in = new DataInputStream(in2);
System.out.println(in.readByte());
System.out.println(in.readLong());
System.out.println(in.readChar());
System.out.println(in.readUTF());
使用数据操作流读写二进制文件
DataOutputStream dos = null;
DataInputStream dis = null;
FileInputStream fis= null;
FileOutputStream fos=null;
try {
//创建输入流文件
fis = new FileInputStream("D:\\doc\\User.class");
dis = new DataInputStream(fis);
//创建输出流文件
fos = new FileOutputStream("D:\\doc\\newUser.class");
dos = new DataOutputStream(fos);
int temp;
while(((temp=dis.read()) != -1)) {
fos.write(temp);
}
6、序列化与反序列化
在 Java 开发中,序列化和反序列化是一种常用的技术,用于将对象转换为字节序列以便存储或传输,并在需要时重新创建对象。下面将详细介绍 Java 中的序列化和反序列化的实现方法。
1.什么是序列化与反序列化
Serialization(序列化):将java对象以一连串的字节保存在磁盘文件中的过程,也可以说是保存java对象状态的过程。序列化可以将数据永久保存在磁盘上(通常保存在文件中)。
deserialization(反序列化):将保存在磁盘文件中的java字节码重新转换成java对象称为反序列化。
java序列化的优点:
- 实现了数据的持久化,通过序列化可以把数据持久地保存在硬盘上(磁盘文件)。
- 利用序列化实现远程通信,在网络上传输字节序列。
实现序列化和反序列化
方法 | 描述 | 类型 |
ObjectOutputStream(OutputStream out) | 创建对象输出流对象 | 构造方法 |
final void writeObject(Object obj) | 将指定对象写入流 | 实例方法 |
使用ObjectOutputStream类实现序列化
例
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
//…
}
ObjectOutputStream oos = null;
//省略异常处理代码
//创建对象
oos = new ObjectOutputStream(
new FileOutputStream("D:\\doc\\person.bat"));
Person person = new Person("杰米", 25, "男");
//对象序列化,写入输出流
oos.writeObject(person);
if(oos!=null) {
//省略异常处理代码
oos.close();
}
使用ObjectInputStream类实现反序列化
例
ObjectInputStream ois = null;
//省略异常处理代码
//创建对象
ois = new ObjectInputStream(new
FileInputStream("D:\\doc\\person.bat"));
//反序列化强制类型转换
Person per = (Person) ois.readObject();
//输出转换反序列化后的对象信息
per.print();
if (ois != null)
ois.close();
限制序列化
将Person类对象中的年龄信息不被序列化
import java.io.Serializable;
public class Person implements Serializable {
private String name;
private transient int age;
private String sex;
public void print() {
System.out.println("姓名:"+this.name+",年龄:"+this.age+",性别:"+this.sex+"。");
}
}