在学习输入/输出流的前提下先了解一下File类。
使用 File 类操作文件
importjava.io.File;importjava.io.IOException;public classFIleTest {public static voidmain(String[] args) {//创建File 类对象
File file = new File("files/file");//创建文件夹,并且只能创建一级文件夹//System.out.println(file.mkdir());//返回 false//可以同时创建多层目录//System.out.println(file.mkdirs());//访问文件名相关的方法
System.out.println("获取文件的名称:"+file.getName());
System.out.println("返回路径名:"+file.getPath());
System.out.println("返回绝对路径:"+file.getAbsolutePath());
System.out.println("返回最后一级子目录对应的父目录名:"+file.getParent());//文件检测相关的方法
System.out.println(file.exists()); //判断文件或者目录是否存在
System.out.println(file.canWrite()); //判断此 file对象所对应的文件或目录是否可写
System.out.println(file.canRead()); //是否可读
System.out.println(file.isFile()); //判断是不是文件
System.out.println(file.isDirectory()); //判断是不是目录
System.out.println(file.isAbsolute()); //判断 File 对象所对应的文件或目录是否是绝对路径//在指定路径下创建新的文件
file = new File("files/file/hello.txt");//判断这个文件是否存在
if (!file.isFile()){try{
file.createNewFile();//不存在就创建一个
} catch(IOException e) {
e.printStackTrace();
}
}
}
}
流的分类:
1.输入流和输出流
按照流的流向来分类,可以分为输入流和输出流。
》输入流:只能从中读取数据,而不能向其写入数据。
》输出流:只能向其写入数据,而不能从中读取数据。
Java中的输入流主要用InputStream 和 Reader 作为基类,而输出流则主要由OutputStream 和 Writer 作为基类。他们都是一些抽象基类,不能直接创建实例。
2.字节流和字符流
字节流和字符流的用法几乎完全一致,区别在于字节流和字符流所操作的数据单元不同——字节流操作的数据单元是 8 位的字节,而字符流操作的数据单元是 16 为的字符。
字节流主要由 InputStream 和 OutputStream 作为基类,而字符流则主要由 Reader 和 Writer 作为基类。
Java 输入/输出流体系中常用的流分类
分类
字节输入流
字节输出流
字符输入流
字符输出流
抽象基类
InputStream
OutPutStream
Reader
Writer
访问文件
FileInputStream
FileOuputStream
FileReader
FileWiter
访问数组
ByteArrayInputStream
ByteArrayOutputStream
CharArrayReaader
CharArrayWriter
访问管道
PipedInputStream
PipedOutputStream
PipedReader
PipedWriter
访问字符流
StringReader
StringWriter
缓存流
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter
转换流
InputStreamReader
OutputStreamWriter
对象流
ObjectInputStream
ObjectInputStream
抽象基流
FilterInputStream
FilterOutputStream
FilterReader
FilterWriter
打印流
PrintStream
PrintWritrt
推回输入流
PushbackInputStream
PushbackReader
特殊流
DataInputStream
DataOutputStream
输入流:
输出流又分为两种 字节输入流(InputStream)和字符输入流(Reader)
》》字节流
importjava.io.File;importjava.io.FileInputStream;importjava.io.IOException;importjava.io.InputStream;public classInputStreamTest {public static void main(String[] args) throwsIOException {//创建字节输入流
InputStream fis = new FileInputStream(new File("files/file/hello.txt"));//创建输入流,可以看成一个“竹筒”
byte[] bbuf = new byte[1024];//用于保存实际读取的字节数
int hasRead = 0;//使用循环重复“取水”的过程
while((hasRead = fis.read(bbuf)) >0){//取出 “竹筒”中的水滴(字节),将字节数组转换成字符串输入
System.out.println(new String(bbuf,0,hasRead));
}//关闭文件输入流
fis.close();
}
}
》》字符流
importjava.io.File;importjava.io.FileReader;importjava.io.IOException;importjava.io.Reader;public classReaderTest {public static voidmain(String[] args) {//创建字符流并且自动关闭流,这样保证输入流一定会关闭
try (Reader fr = new FileReader(new File("files/fils/hello.txt"))){//创建一个长度为32的“竹筒”
char[] cbuf =new char[32];//用于保存实际读取的字符数
int hasRead = 0;//使用循环来重复“取水”的过程
while((hasRead = fr.read(cbuf)) > 0){//取出“竹筒”中的水滴(字符),将字符数组转换成字符串输入
System.out.println(new String(cbuf,0,hasRead));
}
}catch(IOException e) {
e.printStackTrace();
}
}
}
》》使用Reader 和 BufferedReader 读取文本文件
importjava.io.BufferedReader;importjava.io.File;importjava.io.FileReader;importjava.io.IOException;importjava.io.Reader;public classBufferedReaderTest {public static voidmain(String[] args) {/*** BufferedReader类是 Reader 类的一个子类,它与FileReader 类的区别在于,BufferedReader 类带有缓存区,
* 它可以先把一批数据读到缓存区,接下来的读取操作都是从缓存中获取数据,避免每次都从数据源读取数据进行字符
* 编码转换,从而提高读取操作的效率。
**/
//创建字符流 Reader对象
try(Reader fr = new FileReader(new File("files/file/hello.txt"))) {//创建一个 BufferedReader 对象
BufferedReader br =newBufferedReader(fr);//接受读取出的数据
String line = null;//采用循环方式来逐行地读取数据
while((line = br.readLine()) != null){
System.out.println(line);
}
}catch(IOException e) {
e.printStackTrace();
}
}
}
输出流:
输出也是分为两种 字节流(OutputStream) 和 字符流(Writer)
》》字节输出流(OutputStream)
importjava.io.File;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.OutputStream;public classOutputStreamTest {public static voidmain(String[] args) {//创建输入流,以追加方式写入文件
try (OutputStream fos = new FileOutputStream(new File("files/file/hello.txt"),true)){
String str="\n好好学习Java"; //加\n可以自动换行//字节数组
byte[] words =str.getBytes();//写入文件
fos.write(words, 0, words.length);
}catch(IOException e) {
e.printStackTrace();
}
}
}
》》字符输入流(Writer)
importjava.io.File;importjava.io.FileWriter;importjava.io.IOException;importjava.io.Writer;public classWriterTest {public static voidmain(String[] args) {//创建字符输出流,并且以追加方式写入文件
try(Writer fw = new FileWriter(new File("files/file/hello.txt"),true)) {//写入文件
fw.write("Hello Java!");
fw.flush();//刷新缓存区
} catch(IOException e) {
e.printStackTrace();
}
}
}
》》使用BufferedWriter 和 FileWriter 写入文本文件
importjava.io.BufferedWriter;importjava.io.File;importjava.io.FileWriter;importjava.io.IOException;importjava.io.Writer;public classBufferedWrierTest {public static voidmain(String[] args) {try(//创建输出流,并且以追加方式写入文本
Writer fw = new FileWriter(new File("files/file/hello.txt"),true);//创建一个 BufferedWriter 缓存对象
BufferedWriter bw = newBufferedWriter(fw)) {
bw.newLine();//换行
bw.write("我正在学习BufferedWriter");//写入文本
}catch(IOException e) {
e.printStackTrace();
}
}
}
二进制文件的读写:
importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;public classMyTest {public static voidmain(String[] args) {try(//创建字节输入流
InputStream fis = new FileInputStream(new File("F://MyEclipse/MyIO/bin/cn/bdqn/file/FileTest.class"));
DataInputStream dis=newDataInputStream(fis);//创建字节输出流
OutputStream fos = new FileOutputStream(new File("files/file/file.class"));
DataOutputStream dos= newDataOutputStream(fos);
){inttemp;//读取并写入文件
while((temp = dis.read())!=-1){
dos.write(temp);
}
}catch(IOException e) {
e.printStackTrace();
}
}
}
序列化和反序列化:
序列化概述:
简单的说,序列化就是将对象的状态存储到特定存储介质中的过程,也就是将对象转换为可保持或传输格式的过程中,会将对象的公有成员、私有成员(包括类名),转换为字节流,然后再把字节流写入数据流,存储到存储到文件中
用序列化保存对象信息
序列化机制允许将实现序列化的Java对象转换为字节序列,这个需要借助于I/O流来实现。Java 中,只有实现了 java.io.Serializable 接口的类的对象才能被序列化,Serializable 表示串行的、可序列化的,所以对象序列化在某些文献上也称为串行化。
》》创建Student类
importjava.io.Serializable;public class Student implementsSerializable{private static final long serialVersionUID = 1L;privateString name;private intage;privateString sex;privateString address;publicStudent() {
}public Student(String name, intage, String sex, String address) {super();this.name =name;this.age =age;this.sex =sex;this.address =address;
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}public intgetAge() {returnage;
}public void setAge(intage) {this.age =age;
}publicString getSex() {returnsex;
}public voidsetSex(String sex) {this.sex =sex;
}publicString getAddress() {returnaddress;
}public voidsetAddress(String address) {this.address =address;
}
}
》》序列化
importjava.io.File;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.ObjectOutputStream;public classSerializaleTest {public static voidmain(String[] args) {//创建字节输出流
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("files/file/student.txt")))) {
Student stu= new Student("张三",22,"男","北京海定区五道口");
oos.writeObject(stu);
}catch(IOException e) {
e.printStackTrace();
}
}
}
》》反序列化
importjava.io.File;importjava.io.FileInputStream;importjava.io.IOException;importjava.io.ObjectInputStream;public classDeSerializableTest {public static voidmain(String[] args) {//创建字节输入流
try (ObjectInputStream ois =new ObjectInputStream(new FileInputStream(new File("files/file/student.txt")))) {//强制转换成Student 对象
Student stu =(Student)ois.readObject();
System.out.println("姓名:"+stu.getName());
System.out.println("年龄:"+stu.getAge());
System.out.println("性别:" +stu.getSex());
System.out.println("地址:" +stu.getAddress());
}catch(IOException e) {
e.printStackTrace();
}catch(ClassNotFoundException e) {
e.printStackTrace();
}
}
}