在学习输入/输出流的前提下先了解一下File类。
使用 File 类操作文件
import java.io.File; import java.io.IOException; public class FIleTest { public static void main(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 作为基类。
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
抽象基类 | 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)
》》字节流
import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; public class InputStreamTest { public static void main(String[] args) throws IOException { //创建字节输入流 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(); } }
》》字符流
import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.Reader; public class ReaderTest { public static void main(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 读取文本文件
import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.Reader; public class BufferedReaderTest { public static void main(String[] args) { /** * BufferedReader类是 Reader 类的一个子类,它与FileReader 类的区别在于,BufferedReader 类带有缓存区, * 它可以先把一批数据读到缓存区,接下来的读取操作都是从缓存中获取数据,避免每次都从数据源读取数据进行字符 * 编码转换,从而提高读取操作的效率。 * */ //创建字符流 Reader对象 try(Reader fr = new FileReader(new File("files/file/hello.txt"))) { //创建一个 BufferedReader 对象 BufferedReader br =new BufferedReader(fr); //接受读取出的数据 String line = null; //采用循环方式来逐行地读取数据 while((line = br.readLine()) != null){ System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } } }
输出流:
输出也是分为两种 字节流(OutputStream) 和 字符流(Writer)
》》字节输出流(OutputStream)
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; public class OutputStreamTest { public static void main(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)
import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; public class WriterTest { public static void main(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 写入文本文件
import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; public class BufferedWrierTest { public static void main(String[] args) { try( //创建输出流,并且以追加方式写入文本 Writer fw = new FileWriter(new File("files/file/hello.txt"),true); //创建一个 BufferedWriter 缓存对象 BufferedWriter bw = new BufferedWriter(fw)) { bw.newLine(); //换行 bw.write("我正在学习BufferedWriter");//写入文本 } catch (IOException e) { e.printStackTrace(); } } }
二进制文件的读写:
import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class MyTest { public static void main(String[] args) { try ( //创建字节输入流 InputStream fis = new FileInputStream(new File("F://MyEclipse/MyIO/bin/cn/bdqn/file/FileTest.class")); DataInputStream dis =new DataInputStream(fis); //创建字节输出流 OutputStream fos = new FileOutputStream(new File("files/file/file.class")); DataOutputStream dos = new DataOutputStream(fos); ){ int temp; //读取并写入文件 while((temp = dis.read())!=-1){ dos.write(temp); } } catch (IOException e) { e.printStackTrace(); } } }
序列化和反序列化:
序列化概述:
简单的说,序列化就是将对象的状态存储到特定存储介质中的过程,也就是将对象转换为可保持或传输格式的过程中,会将对象的公有成员、私有成员(包括类名),转换为字节流,然后再把字节流写入数据流,存储到存储到文件中
用序列化保存对象信息
序列化机制允许将实现序列化的Java对象转换为字节序列,这个需要借助于I/O流来实现。Java 中,只有实现了 java.io.Serializable 接口的类的对象才能被序列化,Serializable 表示串行的、可序列化的,所以对象序列化在某些文献上也称为串行化。
》》创建Student类
import java.io.Serializable; public class Student implements Serializable{ private static final long serialVersionUID = 1L; private String name; private int age; private String sex; private String address; public Student() { } public Student(String name, int age, String sex, String address) { super(); this.name = name; this.age = age; this.sex = sex; this.address = address; } 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 String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
》》序列化
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; public class SerializaleTest { public static void main(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(); } } }
》》反序列化
import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream; public class DeSerializableTest { public static void main(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(); } } }