> 文档中心 > Java之IO流学习笔记

Java之IO流学习笔记

File的构造器

  • public File(String pathname) 以pathname为路径创建File对象,可以是绝对路径或者相对路径,如果pathname是相对路径,则默认的当前路径在系统属性user.dir中存储。绝对路径:是一个固定的路径,从盘符开始。相对路径:是相对于某个位置开始
  • public File(String parent,String child) 以parent为父路径,child为子路径创建File对象。
  • public File(File parent,String child) 根据一个父File对象和子文件路径创建File对象

File类的获取功能

  • public String getAbsolutePath():获取绝对路径
  • public String getPath():获取路径
  • public String getName():获取名称
  • public String getParent():获取上层文件目录路径。若无,返回null
  • public long length():获取文件长度(即:字节数)。不能获取目录的长度
  • public long lastModified():获取最后一次的修改时间,毫秒值
  • public String[]list():获取指定目录下的所有文件或者文件目录的名称数组
  • public File[] listFiles():获取指定目录下的所有文件或者文件目录的File数组

File类的重命名功能

​ public boolean renameTo(File dest):把文件重命名为指定的文件路径。重命名到的文件目录不能存在

File类的判断功能

  • public boolean isDirectory():判断是否是文件目录
  • public boolean isFile():判断是否是文件
  • public boolean exists():判断是否存在
  • public boolean canRead():判断是否可读
  • public boolean canWVrite():判断是否可写
  • public boolean isHidden() :判断是否隐藏

File类的创建功能

  • public boolean createNewFile() :创建文件。若文件存在,则不创建,返回false
  • public boolean mkdir() :创建文件目录。如果此文件目录存在,就不创建了。如果此文件目录的上层目录不存在,也不创建。
  • public boolean mkdirs(): 创建文件目录。如果上层文件目录不存在,一并创建注意事项:如果你创建文件或者文件目录没有写盘符路径,那么,默认在项目路径下。

File类的删除功能

  • public boolean delete():删除文件或者文件夹
  • 删除注意事项:
    1. Java中的删除不走回收站。
    2. 要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录

流的分类

按照流的流向分:输入流,输出流

按照流的角色分:节点流,处理流

按照流的数据单元:字符流(16bit),字节流(8bit)

抽象基类 字节流 字符流
输入流 InputStream Reader
输出流 OutputStream Writer

Java的IO流共涉及40多个类,实际上非常规则,都是从4个抽象基类派生出来的,

由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀
在这里插入图片描述

FileWriter读出数据

创建hello.txt文件写入hello字符串

 public static void main(String[] args) throws IOException { File file = new File("hello.txt"); FileReader fileReader = new FileReader(file);/*方式一int read = fileReader.read(); while (read != -1) {     System.out.print((char) read);     read= fileReader.read(); } */  /* 方式二 int read ; while ((read=fileReader.read()) != -1) {     System.out.print((char) read); } */      char[] chars = new char[12]; int leng; while ((leng = fileReader.read(chars)) != -1) {//     第一种写法读法//     for (int i = 0; i < leng; i++) {//  System.out.print(chars[i]);//     }//     第二种读法     String string = new String(chars,0,leng);     System.out.print(string);      fileReader.close();    }// 结果输出 hello

FileWriter写入数据

 public static void main(String[] args) throws IOException { File file = new File("hello.txt"); FileWriter fileWriter = new FileWriter(file); fileWriter.write("hello word");// 覆盖写入 fileWriter.append(" hello java"); // 追加写入 new FileWriter(file,true)用此方式,write写入也是追加方式 fileWriter.close();    }

小例子:数据先读出在写入另一个文件

  public static void main(String[] args)  { FileReader fileReader = null; FileWriter fileWriter = null; try {     File file = new File("hello.txt");     File file1 = new File("hello1.txt");     fileReader = new FileReader(file);     fileWriter = new FileWriter(file1,true);     char[] chars = new char[12];     int len;     while ((len = fileReader.read(chars)) != -1) {  // 方式一//  fileWriter.write(chars,0,len);  // 方式二  String string = new String(chars, 0, len);  fileWriter.write(string);     } } catch (IOException e) {     e.printStackTrace(); } finally {     try {  if (fileReader!=null)fileReader.close();     } catch (IOException e) {  e.printStackTrace();     }     try {  if (fileWriter!=null) fileWriter.close();     } catch (IOException e) {  e.printStackTrace();     } }    }

FileInputStream和FileOutputStream读写非文本文件

 public static void main(String[] args) { FileInputStream inputStream = null; FileOutputStream outputStream = null; try {      inputStream = new FileInputStream("1.jpg");      outputStream = new FileOutputStream("2.jpg");     byte[] bytes = new byte[1024];     int len;     while ((len = inputStream.read(bytes)) != -1) {  outputStream.write(bytes, 0, len);     } } catch (IOException e) {     e.printStackTrace(); } finally {     try {  if (inputStream!=null)  inputStream.close();     } catch (IOException e) {  e.printStackTrace();     }     try {  if (outputStream!=null)  outputStream.close();     } catch (IOException e) {  e.printStackTrace();     } }    }

使用BufferedInputStream和BufferedOutputStream

     public static void main(String[] args) { FileInputStream inputStream = null; FileOutputStream outputStream = null; BufferedInputStream bufferedInputStream = null; BufferedOutputStream bufferedOutputStream = null; try {     File file = new File("1.jpg");     File file1 = new File("4.jpg");     inputStream = new FileInputStream(file);     outputStream = new FileOutputStream(file1);      bufferedInputStream = new BufferedInputStream(inputStream);bufferedOutputStream = new BufferedOutputStream(outputStream);     byte[] bytes = new byte[1024];     int len;     while ((len=bufferedInputStream.read(bytes))!=-1) {  bufferedOutputStream.write(bytes, 0, len);//  bufferedOutputStream.flush(); 刷新缓冲区     } } catch (IOException e) {     e.printStackTrace(); } finally { // 关闭外层缓冲流,内层自动关闭      try {  if (bufferedInputStream!=null)  bufferedInputStream.close();     } catch (IOException e) {  e.printStackTrace();     }     try {  if (bufferedOutputStream!=null)  bufferedOutputStream.close();     } catch (IOException e) {  e.printStackTrace();     } }    }

bufferedReader和bufferedWriter针对文件操作

  public static void main(String[] args)  { BufferedReader bufferedReader = null; BufferedWriter bufferedWriter = null; try {     bufferedReader = new BufferedReader(new FileReader("hello.txt"));     bufferedWriter = new BufferedWriter(new FileWriter("hello1.txt"));     char[] ch = new char[12];     int len;     while ((len = bufferedReader.read(ch)) != -1) {  bufferedWriter.write(ch, 0, len);     } } catch (IOException e) {     e.printStackTrace(); } finally {     try {  if (bufferedWriter!=null)  bufferedWriter.close();     } catch (IOException e) {  e.printStackTrace();     }     try {  if (bufferedReader!=null)  bufferedReader.close();     } catch (IOException e) {  e.printStackTrace();     } }    }

对象流ObjectInputStream和OjbectOutputSteam

  • 用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。
  • 序列化:用ObjectOutputStream类保存基本类型数据或对象的机制
  • 反序列化:用ObjectInputStream类读取基本类型数据或对象的机制
  • ObjectOutputStream和ObjectlnputStream不能序列化staticltransient修饰的成员变量

对象的序列化

  • 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象
  • 序列化的好处在于可将任何实现了Serializable接口的对象转化为字节数据,使其在保存和传输时可被还原
  • 序列化是RMI (Remote Method Invoke-远程方法调用)过程的参数和返回值都必须实现的机制,而RMI是 JavaEE的基础。因此序列化机制是JavaEE平台的基础
  • 如果需要让某个对象支持序列化机制,则必须让对象所属的类及其属性是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一。否则,会抛出NotSerializableException异常(1. Serializable 2. Externalizable)

序列化 编码

 public static void main(String[] args)  { ObjectOutputStream objectOutputStream = null; try {     objectOutputStream = new ObjectOutputStream(new FileOutputStream("ser.txt"));     objectOutputStream.writeObject("哈哈哈哈哈");     objectOutputStream.flush(); } catch (IOException e) {     e.printStackTrace(); } finally {     try {  if (objectOutputStream!=null)      objectOutputStream.close();     } catch (IOException e) {  e.printStackTrace();     } }    }

反序列化输出数据到控制台(反编码)

    ObjectInputStream objectInputStream = null; try {     objectInputStream = new ObjectInputStream(new FileInputStream("ser.txt"));     String o = (String) objectInputStream.readObject();     System.out.println(o); } catch (IOException | ClassNotFoundException e) {     e.printStackTrace(); } finally {     try {  if (objectInputStream!=null)  objectInputStream.close();     } catch (IOException e) {  e.printStackTrace();     } }

凡是实现Serializable接口的类都有一个表示序列化版木标识符的静态变量: private static final long serialversionUID;

serialVersionUID用来表明类的不同版本间的兼容性。简言之,其目的是以序列化对象进行版本控制,有关各版本反序列化时是否兼容。
如果类没有显示定义这个静态变量,它的值是Java运行时环境根据类的内部细节自动生成的。若类的实例变量做了修改,serialVersionUID可能发生变化。故建议,显式声明。
简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的
serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)

RandomAccessFile

  • RandomAccessFile声明在java.io包下,但直接继承于java.lang.Object类。并且它实现了Datalnput、DataOutput这两个接口,也就意味着这个类既可以读也可以写。
  • RandomAccessFile类支持“随机访问”的方式,程序可以直接跳到文件的任意地方来读、写文件
    • 支持只访问文件的部分内容
    • 可以向已存在的文件后追加内容
  • RandomAccessFile对象包含一个记录指针,用以标示当前读写处的位置。RandomAccessFile类对象可以自由移动记录指针:
    • long getFilePointer(): 获取文件记录指针的当前位置
    • void seek(long pos):将文件记录指针定位到pos位置
    • 在这里插入图片描述
      我们可以用RandomAccessFile这个类,来实现一个多线程断点下载的功能,用过下载工具的朋友们都知道,下载前都会建立两个临时文件,一个是与被下载文件大小相同的空文件,另一个是记录文件指针的位置文件,每次暂停的时候,都会保存上一次的指针,然后断点下载的时候,会继续从上一次的地方下载,从而实现断点下载或上传的功能,有兴趣的朋友们可以自己实现下。

小故事网