• 第54节:Java当中的IO流(中)


    标题图

    Java当中的IO流(中)

    删除目录

    // 简书作者:达叔小生
    
    import java.io.File;
    
    public class Demo{
     public static void main(String[] args){
    
      // 目录
      File dir = new File("E:\hello");
     // 删除目录
     System.out.println(dir.delete());
    // removeDir(dir); 
    // 下方方法
     }
    }
    

    如果目录里面有文件,或者还有目录,就无法删除,会显示为false的,那么就要从里头往外进行删除,可以进行递归的方法.

    进行删除里头文件或文件夹

    public static void removeDir(File dir){
    
     // 使用listFiles()方法,查看目录下是否有文件以及文件夹
     File[] files = dir.listFiles();
    
     // 如果没有目录
     if(files.length==0){
      dir.delete();
      return;
     }
    
     if(files!=null){
     for(File file : files){
      // 进行遍历files对象,判断是否是目录
      if(file.isDirectory()){
     // 进行删除目录
       removeDir(file);
      }else{
      // 进行删除文件
       System.out.println(file+":"+file.delete());
      }
     }
     }
     System.out.println(dir+":"+dir.delete());
    }
    

    对学生信息进行存储

    创建学生类:

    public class Student implements Comparable<Student>{
    
     private String name;
     private int cn, en, ma;
     private int sum;
    
     public Student(String name, int cn, int en, intma){
      super();
      this.name = name;
      this.cn = cn;
      this.en = en;
      this.ma = ma;
      this.sum = cn + en + ma;
     }
    
     public Student(){
      super();
     }
    
     // compareTo
     @Override
     public int compareTo(Student o){
    
      int temp = this.sum - o.sum;
      
      return temp==0 ? this.name.compareTo(o.name):temp;
     }
    
     @Override
     public int hashCode(){
      final int prime = 31;
      int result = 1;
      result = prime + result + cn;
      result = prime + result + sum;
      return result;
     }
     
     public String getName(){
      return name;
     }
     public void setName(String name){
      this.name = name;
     }
    
     public void setCn(int cn){
      this.cn = cn;
     }
     public int getCn(){
      return cn;
     }
    
     public void setEn(int en){
      this.en = en;
     }
     public int getMa(){
      return ma;
     }
    
     public void setMa(int ma){
      this.ma = ma;
     }
     public int getSum(){
      return sum;
     }
    
     public void setSum(int sum){
      this.sum = sum;
     }
    
     @Override
     public String toString(){
      return "Student [name=" + name + ", sum=" + sum + "]";
     }
    }
    

    将学生的成绩等按照分数排序:

    将信息保存到文件,就要使用IO流,有很多学生就要存储集合

    // 简书作者:达叔小生
    
    public class Demo {
     private static final String LINE_SEPARATOR = System.getProperty("line.separator");
    
     public static void main(String[] args) throws IOException {
    
      Set<Student> set = new TreeSet<Student>(Collections.reverseOrder());
    
      set.add(new Student("da",12,34,55));
      set.add(new Student("shu",23,44,53));
      set.add(new Student("dashu",24,12,34));
    
      // 创建目录,对应目录
    
      File dir = new File("Student");
    
      // 如果目录不存在就创建
    
      if(!dir.exists()){
       dir.mkdir();
      }
    
     // 对应目录下的文件
      File desFiles = new File(dir,"student_info.txt");
     // 把数据写入到文件中
      writeToFile(set,desFiles);
     
     }
    
     // 方法writeToFile(set,desFiles);
     public static void writeToFile(Set<Student> set, File desFile ) throws IOException {
    
     FileOutputStream fos = null;
    
     try{
      fos = new FileOutputStream(desFile);
      // 遍历对象
      for(Student stu:set){
       String info = stu.getName() + "	" + stu.getSum() + LINE_SEPARATOR;
       // 数据写到文件中
       fos.write(info.getBytes());
      }
     }finally{
      if(fos!=null){
     try{
      // 关闭资源
      fos.close();
      }catch(IOException e){
      throw new RuntimeException("系统资源关闭失败");
     }
     }
     }
     }
    }
    

    文件清单,就是获取目录中的文件,使用递归的方法,通过过滤器找到指定的所有文件.

    public class Demo{
    
     private static final String LINE_SEPARATOR = SeparatorTool.LINE_SEPARATOR;
    
     public static void main(String[] args) throws IOException {
     // 明确一个目录
      File dir = new File("E:\hello");
    
     // 过滤器 创建类 FileFilterByJava
     FileFilter filter = new FileFilterBySuffix(".java"); 
    
     // 创建集合
     List<File> list = new ArrayList<File>();
    
      // 指定文件清单
      getFileList(dir,filter,list);
     System.out.println(list.size());
     
     File desFile = new File(dir,"javalist.txt");
     writeToFile(list,desFile);
     }
    
    // 方法writeToFile
    
    public static void writeToFile(List<File> list, File desFile) throws IOException {
    
     FileOutputStream fos = null;
     BufferedOutputStream bufos = null;
    
     try{
      fos=new FileOutputStream(destFile);
      bufos=new BufferedOutputStream(fos);
    
      for(File file : list){
      String info = file.getAbsolutePath()+LINE_SEPARATOR
      bufos.write(info.getBytes());
      bufos.flush();
      }
      }finally{
       if(bufos!=null){
        try{
         fos.close();
        }catch(IOException e){
         throw new RuntimeException("关闭失败");
        }
       }
      }
    }
    
     public static void getFileList(File dir, FileFilter filter, List<File> list){
      // 获取目录下的子目录
     File[] files = dir.llistFiles();
     // 过滤器
     
     // 遍历子目录
     for(File file : files){
      // 进行判断是否是目录,如果是进行递归
      if(file.isDirectory()){
       // 进行递归
       getFileList(file,filter,list);
      }else{
       // if(file.getName().endsWith(".java")){
        if(filter.accept(file)){
         list.add(file);
        }
       }
      }
     }
    }
    

    FileFilterByJava:

    // 简书作者:达叔小生
    
    import java.io.File;
    
    public class FileFilterBySuffix implements FileFilter {
    
     private String suffix;
     public FileFilterBySuffix(String suffix){
      super();
      this.suffix = suffix;
     }
    
     @Override
     public boolean accept(File pathname) {
      return pathname.getName().endsWith(suffix);
     }
    }
    

    分隔符工具:

    public class SeparatorTool {
    
     private SeparatorTool(){
      super();
     }
    
     public static final String LINE_SEPARATOR = System.getProperty("line.separator");
     public static final String PATH_SEPARATOR = System.getProperty("path.separator");
     public static final String FILE_SEPARATOR = System.getProperty("file.separator");
    }
    

    字节流输入和输出,字符流,字节流读取字符
    InputStream和OutputStream
    FileInputStream和FileOutputStream
    BufferedInputStream和BufferedOutputStream

    // 简书作者:达叔小生
    
    public class CharStreamDemo{
     public static void main(String[] args) throws IOException{
    
       // writeCNText();
      FileInputStream fis = new FileInputStream("dashu\dashu.txt");
     // 如何判断? 一个中文默认为两个字节
     byte[] buff = new byte[1024];
     int len = 0;
    
     while( (len = fis.read(buff) != -1){
      String str = new String(buff,0,len);
      System.out.println(str);
     }
     fis.close();
     }
     
     public static void readCNText() throws FileNotFoundException{
    
     FileInputStream fis = new FileInputStream("dashu\dashu.txt");
     
     }
    
     public static void writeCNText() throws FileNotFoundException, IOException{
    
      FileOutputStream fos = new FileOutputStream("dashu\dashu.txt");
      fos.write("简书作者:达叔小生".getBytes());
      fos.close();
     }
    
    }
    

    编码表

    编码表 ASCII 美国标准信息交换码
    将生活中的一切用计算机的二进制进行对应表示关系表
    中文的,GB2312,用两个字节表示,6到7千
    GBK,常用的中文码表,用两字节表示,2万多
    unicode为国际标准码表,用两个字节表示
    UTF-8是基于unicode的,用一个字节存储,更加标准.

    // Java中
    
    char c = 'a';
    无论什么都是两个字节
    

    字符流FileReader

    解码和编码

    字符串
    构造方法

    方法 说明
    String() 是初始化一个String对象,表示一个空字符序列
    String(byte[] byte) 是使用平台默认的字符集解(默认的字符集为gbk)码指定的byte的数组
    String(byte[] bytes, Charset charset) 是通过使用指定的charset解码指定的byte数组

    FileInputStream

    java.lang.Object
    -> java.io.InputStream
    -> java.io.FileInputStream
    
    public class FileInputStream extends InputStream
    从文件系统中的某个文件中获取输入字节
    

    如果要读取字符流,就要用FileReader.

    字节流是用FileInputStream哦~


    读取字符文件的 FileReader

    java.io
    
    类 FileReader
    
    java.lang.Object
    
    -> java.io.Reader
    
    -> java.io.InputStreamReader
    
    -> java.io.FileReader
    
    public class FileReader extends InputStreamReader
    

    此类的构造方法自带默认的字符集编码和字节缓冲区,FileReader用于读取字符流.

    // 简书作者:达叔小生
    
    // 版本开始为JDK1.1
    
    FileInputStream -> InputStreamReader
    

    FileReader类是一个操作字符文件的便捷类,有默认的字符集编码和字节缓冲区

    FileReader的构造方法:

    方法 说明
    FileReader(File file) 是用来给定从中读取数据的File
    FileReader(FileDescriptor fd) 是给定从中读取数据的FileDescriptor
    FileReader(String fileName) 是用来读取数据的文件名

    java.io.InputStreamReader继承的方法

    close, getEncoding, read, ready
    

    java.io.Reader继承的方法

    mark, markSupported, read, reset, skip
    

    基础顶层

    java.io
    
    类 Reader
    
    java.lang.Object
    
    -> java.io.Reader
    

    用于读取字符流的抽象类 Reader
    public abstract class Reader extends Object
    implements Readable, Closeable


    Reader方法:

    close()为关闭该流,并且释放所有资源
    
    mark(int readAheadLinmit)为标记流中的当前位置
    markSupported()为判断此流是否支持mark()
    
    read()为读取单个字符
    read(char[] cbuf)为将字符读入数组
    read(char[] sbuf, int off, int len)为将字符一部分读入数组
    read(CharBuffer target)为试图将字符读入指定的字符缓冲区
    
    ready()为判断是否准备读取此流
    reset()为重置此流
    skip(long n)为跳过字符
    

    FileReader代码:

    FileReader fr = new FileReader("dashu\dashu.txt");
    
    int ch = fr.read();
    System.out.println(ch);
    fr.close();
    
    int ch = 0;
    int count = 0;
    
    while((ch=fr.read()) != -1){
     if(ch=='好'){
      count++;
     }
    }
    
    System.out.println("count =" + count);
    

    字符流FileWriter

    java.io
    
    类 Writer
    
    java.lang.Object
    
    -> java.io.Writer
    
    public abstract class Writer extends Object 
    implements Appendable, Closeable, Flushable
    
    写入字符流的抽象类
    

    FileWriter

    FileWriter是用来写入字符文件的便捷类

    FileOutputStream -> OutputStreamWriter
    
    public class FileWriter extends OutputStreamWriter
    
    java.io 类 FileWriter
    
    java.lang.Object
    
    -> java.io.Writer
    
    -> java.io.OutputStreamWriter
    
    -> java.io.FileWriter
    

    FileWriter此类的构造方法是假定默认的字符编码和默认的字节缓冲区大小,FileWriter是用于写入字符流

    FileWriter(File file)
    FileWriter(File file, boolean append)
    
    FileWriter(FileDescriptor fd)
    
    FileWriter(String fileName)
    FileWriter(String fileName, boolean append)
    

    FileWriter代码例子:

    // 输出流
    import java.io.FileWriter;
    
    public class FileWriterDemo{
     public static void main(String[] args) throws IOException {
    
      // FileWriter, 如果不存在创建一个
      FileWriter fw = new FileWriter("dashu\dashu.txt");
      fw.write("简书作者:达叔小生");
      fw.flush();
      fw.close();
     }
    }
    

    flush()和close()

    flush为刷新该流的缓冲,将流中缓冲区的数据刷新到目的地,刷新后的流可以使用

    public abstract void flush() throws IOException
    

    close为关闭此流,关闭流之前要先刷新,关闭资源用的,在关闭前会将缓冲区里的数据刷新到目的地,然后在关闭流,关闭了就不可以在使用了.

    public void close(){
     flush();
    }
    
    // 简书作者:达叔小生
    public abstract void close() throws IOException
    

    异常:

    java.io.IOException: Steam closed
    

    OutputStreamWriter字符流

    FileOutputStream -> OutputStreamWriter
    

    FileWriterFileReader都是有默认的字符集编码,如GBK

    字符流通过字节流的桥梁类是
    OutputStreamWriter类 -> java.io

    可以用charset将写入流中的字符编码为字节
    OutputStreamWriter默认的字符集可以给定,否则为平台默认

    java.lang.Object
    
    -> java.io.Writer
    
    -> java.io.OutputStreamWriter
    
    public class OutputStreamWriter extends Writer
    

    效率:OutputStreamWriter -> BufferedWriter

    Writer out = new BufferedWriter(new OutputStream(System.out));
    

    OutputStreamWriter方法:

    OutputStreamWriter(OutputStream out)为使用默认的字符编码
    OutputStreamWriter(OutputStream out, Charset cs)为使用给定的字符集编码
    

    OutputStreamWriter例子

    // GBK UTF-8
    public class Demo{
     public static void main(String[] args) throws UnsupportedEncodingException, IOException {
      // 有的人用的却是UTF-8
      OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("dashu\dashu.txt"), "utf-8" );
      osw.write("简书作者:达叔小生");
      osw.close();
     }
    }
    

    升级:

    // 导致乱码
    public static void read() throws IOException{
    
     FileReader fr = new FileReader("dashu\dashu.txt");
     // int ch = (char)fr.read();
    
     char[] buff = new char[1024];
     int len = fr.read(buff);
     System.out.println(new String(buff,0,len);
     fr.close();
    }
    

    字符流 InputStreamReader

    java.io
    
    类 InputStreamReader
    
    java.lang.Object
    
    -> java.io.Reader
    
    -> java.io.InputStreamReader
    
    public class InputStreamReader extends Reader
    

    InputStreamReader是用来指定编码读取中文的,是字节流通向字符流的桥梁,可以用charset读取字节并解码为字符.

    为了提高效率,可以BufferedReader内包装InputSteamReader

    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    

    InputStreamReader例子:

    构造方法:

    InputStreamReader(InputStream in)
    InputStreamReader(InputStream in, Charset cs)
    InputStreamReader(InputStream in, CharsetDecoder dec)
    InputStreamReader(InputStream in, String charsetName)
    

    InputStreamReader方法:

    // 简书作者:达叔小生
    close()
    getEncoding()
    read()
    read(char[] cbuf, int offset, int length)
    ready()
    
    public static void read() throws IOException {
     // 创建InputStreamReader对象
     InputStreamReader isr = new InputStreamReader(new FileInputStream("dashu\dashu.txt"), "utf-8");
     
    char[] buff = new char[1024];
     int len = isr.read(buff);
     System.out.println(new String(buff,0,len));
     isr.close();
    }
    // InputStreamReader  Console输出
    

    IO流-InputStreamReader和OutputStreamWriter 转换流

    // 简书作者:达叔小生
    
     InputStreamReader isr = new InputStreamReader(new FileInputStream("dashu\dashu.txt"), "GBK");
     
     char[] buff = new char[1024];
     int len = isr.read(buff);
     System.out.println(new String(buff,0,len));
     isr.close();
    

    InputStreamReader的子类为FileReader
    OutputStreamWriter的子类为FileWriter

    在上面有写到字符流和字节的桥梁为OutputStreamWriterInputStreamReader,所以称为字符转换流

    其字符转换流原理为字节流和编码表

    字符流通过字节流的桥梁类是
    OutputStreamWriter类 -> java.io
    可以用charset将写入流中的字符编码为字节

    InputStreamReader 是用来指定编码读取中文的,是字节流通向字符流的桥梁

    FileWriterFileReaderOutputStreamWriterInputStreamReader的子类,只是用来操作字符文件的便捷类,使用的是默认的编码表.

    如果要使用其他编码时,要使用字符转换流,反之操作的是文件,且用默认的编码时,就使用FileWriterFileReader.

    不转换:

    FileReader fr = new FileReader("dashu.txt");
    

    转换流:

    InputStreamReader isr = new InputStreamReader(new FileInputStream("dashu.txt"), "GBK");
    

    要点

    字节到字符, 输入流, 为InputStreamReader, 是需要读的,
    读的是要给人懂的得,才能读,从看不懂的到看得懂的.

    字符到字节, 输出流, 为OutputStreamWriter, 是需要写的,
    写的是从看懂的到看不懂.

    用字符流复制文本文件

    public class CopyTextFileTest{
     public static void main(String[] args) throws IOException {
      copyTextFile();
     }
    
     public static void copyTextFile() throws IOException {
      // 明确目标
     FileReader fr = new FileReader("dashu.java");
     // 明确目的
     FileWriter fw = new FileWriter("hello\hello.txt");
    
     // 循环,读字符
     // int ch = 0;
     // while((ch=fr.read()) != -1){
     // fw.write(ch);
     // }
    
     // 效率高的
     char[] buff = new char[1024];
     int len = 0;
     while((len=fr.read(buff) != -1){
      fw.write(buff,0,len);
     }
     // 关闭资源
     fw.close();
     fr.close();
     }
    }
    

    字符流缓冲区对象复制文本文件

    java.io
    
    类 Reader
    
    java.lang.Object
    
    -> java.io.Reader
    
    public abstract class Reader extends Object
    
    implements Readable, Closeable
    

    Reader是用来读取字符流的抽象类

    // 简书作者:达叔小生
    BufferedReader
    BufferedWriter
    

    字符输入流中读取文本-BufferedReader

    缓冲区是给流的

    java.io
    
    类 BufferedReader
    
    java.lang.Object
    
    -> java.io.Reader
    
    -> java.io.BufferedReader
    
    从字符输入流中读取文本,用来缓冲各个字符
    
    public class BufferedReader extends Reader
    

    FileReaderInputStreamReader

    BufferedReader in = new BufferedReader(new FileReader("dashu.txt"));
    

    BufferedReader 的构造方法:

    // 简书作者:达叔小生
    BufferedReader(Reader in)为默认大小
    BufferedReader(Reader in, int sz)使用指定的大小
    

    BufferedReader的方法

    方法 说明
    close() 返回类型为void,是用来关闭资源的
    mark(int readAheadLimit) 返回类型为void, 是用来标记流中的当前位置
    markSupported() 返回类型为boolean, 判断此流是否支持mark()操作
    read() 返回类型为int,是用来读取单个字符的
    read(char[] cbuf, int off, int len) 返回类型为Int,是将字符数组一部分读入
    readLine() 返回类型为String, 是用来读取一个文本的
    ready() 返回类型为boolean, 是用来判断此流是否已经准备好
    reset() 返回为void, 是将流重置到最新的标记
    skip(long n) 返回类型为long, 是用来跳过字符的

    将文本写入到字符输出流-BufferedWriter

    java.io
    
    类 BufferedWriter
    
    java.lang.Object
    
    -> java.io.Writer
    
    -> java.io.BufferedWriter
    
    public class BufferedWriter extends Writer
    
    将文本写入字符输出流
    

    FileWriterOutputStreamWriter

    PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("dashu.txt"));
    

    BufferedWriter 的方法

    方法 说明
    close() 返回类型为void,是用来关闭资源的
    flush() 返回类型为void,是用来刷新该流的缓冲
    newLine() 返回类型为void,是用来写入一个行分隔符
    write(char[] cbuf, int off, int len) 返回类型为void, 是用来写入字符数组的一部分
    write(int c) 返回类型为void,是用来写入单个字符
    write(String s, int off, int len) 返回类型为void, 写入字符串的一部分

    字符流的缓冲区

    // 简书作者:达叔小生
    
    public class CharStreamBufferedDemo{
     public static void main(String[] args) throws IOException {
    
      // BufferedReader和BufferedWriter 字符流缓冲区
     // BufferedReader
     // 从字符输入流中读取文本,用来缓冲各个字符
     // BufferedWriter 
     // 将文本写入到字符输出流
    
     copyTextByBuffer();
     readText();
     writeText();
     }
    
     public static void writeText()  throws IOException {
    
      BufferedWriter b = new BufferedWriter(new FileWriter("hello.java");
    
      for(int x=1, x<=4; x++){
       b.write(x);
       b.newLine();
       b.flush();
      }
      b.close();
     }
    
     public static void readText() throws IOException {
    
      BufferedReader buffer = new BufferedReader(new FileReader("dashu.java");
    
      // String line = buffer.readLine();
      // System.out.println(line);
    
     String line = null;
     while((line=buffer.readLine()) != null){
      System.out.println(line);
     }
      buffer.close();
     }
    
     public static void copyTextByBuffer(){
    
      BufferedReader bufr = new BufferedRead(new FileReader("hello.txt"));
      BufferedWriter bufw = new BufferedWriter(new FileWriter("hello\dashu.txt"));
    
      // 循环
     String line = null;
     while((lline = bufr.readLine() != null){
       bufr.write(line);
       bufr.newLine();
       bufr.flush();
      }
      bufw.close();
      bufr.close();
     }
    }
    

    流是一连流串的字符,是信息的通道,分输出流和输入流。

    IO的分类

    第一种分:输入流和输出流。
    第二种分:字节流和字符流。
    第三种分:节点流和处理流。

    Java中流的分类:

    流的运动方向,可分为输入流和输出流两种。

    流的数据类型,可以分为字节流和字符流。

    输入流类都是抽象类
    InputStream(字节输入流)或抽象类Reader类(字符输入流)的子类。

    输出流类都是抽象类
    OutputStream(字节输出流)或抽象类Writer类(字符输出流)的子类。

    输入流从文件输入为读取输出流从文件输出为写入数据

    输入流
    输入流用于读取数据,用户可以从输入流中读取数据,但不能写入数据。

    输入流读取数据过程如下:
    (1)打开一个流。
    如:FileInputStream inputFile=new FileInputStream("数据源");
    (2)从信息源读取信息。
    如:inputFile.read();
    (3)关闭流。
    如:inputFile.close();

    输出流
    输出流用于写入数据。只能写,不能读。

    写数据到输出流过程如下:
    (1)打开一个流。
    如:FileOutputStream outFile=new FileOutputStream("数据源");
    (2)写入信息到目的地。
    如:outFile.write(inputFile.read()):
    (3)关闭流。
    如:outFile.close();

    字符流ReaderWriter

    字节字符转换流:

    // 简书作者:达叔小生
    InputStreamReader
    OutputStreamWriter
    

    往后余生,唯独有你
    简书作者:达叔小生
    90后帅气小伙,良好的开发习惯;独立思考的能力;主动并且善于沟通
    简书博客: https://www.jianshu.com/u/c785ece603d1

    结语

    • 下面我将继续对 其他知识 深入讲解 ,有兴趣可以继续关注
    • 小礼物走一走 or 点赞
  • 相关阅读:
    TCP/IP的基本概念知识
    Mysql查询今天、昨天、7天、近30天、本月、上一月数据
    PHP OOP面向对象部分方法归总(代码实例子)
    PHP 变量
    PHP超级全局变量、魔术变量和魔术函数
    PHP编程效率的20个要点
    MemCache超详细解读
    CodeForces 652E Pursuit For Artifacts 边双连通分量
    HDU 2460 Network 边双连通分量 缩点
    HDU 3594 Cactus 有向仙人掌图判定
  • 原文地址:https://www.cnblogs.com/dashucoding/p/9761017.html
Copyright © 2020-2023  润新知