Java教程

Java-文件、IO流

本文主要是介绍Java-文件、IO流,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

File类型

  • 1、什么是文件?
    • 文件可以认为是相关记录或存放在一起的数据的集合
    • 文件一般是存放在存储设备上的,例如:硬盘、光盘和移动存储设备等等
  • 2、java.io包是JDK内置的包,其中包含一系列对文件和目录的属性进行操作,对文件进行读写操作的类;
    • 程序中如果要使用到该包中的类,对文件或流进行操作,则必须显式地声明如下语句:

import java.io.*

  • 3、文件系统的一般文件组织形式

 

    • 文件系统中由文件夹目录和数据文件构建成一颗树
  • 4、java.io.File类的对象可以表示文件 目录,在程序中一个File类对象可以代表一个文件或目录
    • 当创建一个File对象后,就可以利用它来对文件或目录的属性进行操作,如:文件名、最后修改日期、文件大小等等
    • 需要注意的是,File对象并不能直接对文件 内容 进行读 / 写操作,只能查看文件的属性
  • 5、File类的构造方法有4种重载方式,常用的如下:

  • 6、构建File对象是需要注意的要点:
    • 提供给构造方法的路径可以指向一个具体的文件,这时候File对象能够操作这个文件的属性,也可以指向一个文件夹,这时候File对象操作的就是文件夹的属性
    • 注意上例第二个对象的路径表达,由于在Java中“\”符号表示转意,因此如果使用”\”作为路径分割符,则实际需要编写“\”,当然一个更好的替代方法是使用Unix系统中常用的”/”作为路径分割,则不需要转义
    • 特别注意,Java中的相对路径体系和我们日常所见的文件系统相对路径体系有较大的区别:
    • 如果以路径以“/”或“\”开头,则相对路径的根为当前项目所在磁盘的根目录(Unix没有磁盘分区的概念,因此直接使用/,即文件系统的根作为相对路劲的根)
    • 如果不以“/”开头则相对路径的根为项目根目录,而不是当前类所在目录,这一点非常容易引起误区,因为类从属于某个包之后,类文件实际是位于项目中的某个子文件夹中的,如com.chinasoft.Hello这个类是位于项目中的com\chinasofti子文件夹中,如果在Hello类中构建一个File对象:FIle f = new File(“icss/chinasofti.txt”),那么这个文件位于项目根目录的icss子文件中,跟当前类自己的位置无关 

File对文件的基础操作

  • File(String path):如果 path 是实际存在的路径,则该 File 对象表示的是目录;如果 path 是文件名,则该 File 对象表示的是文件。

  • 举例:
    import java.io.File;
    
    public class TestFile {
        public static void main(String[] args) {
            File file = new File("C:/Users/hzw/Desktop/carat/yi.txt");
            File file1 = new File("yi.txt");
            File file2 = new File("/yi.txt");
            System.out.println(file.exists());
            System.out.println(file.isFile());
            System.out.println(file.isDirectory());
            //无论文件存不存在,名称都是yi.txt
            System.out.println(file.getName());
            //绝对路径
            System.out.println(file.getAbsolutePath());
            //"yi.txt" : 项目所在路径+yi.txt
            System.out.println(file1.getAbsolutePath());
            //"/yi.txt" : Linux(Unix)中 根路径+yi.txt ; Windows中 项目所在盘符+yi.txt
            System.out.println(file2.getAbsolutePath());
            System.out.println(file.length());//0
        }
    }
  • 更多的文件操作
    import java.io.File;
    import java.io.IOException;
    
    public class TestFile1 {
        public static void main(String[] args) throws IOException {
            File file = new File("C:/Users/hzw/Desktop/carat/yi");
            //创建
            boolean newFile = file.createNewFile();
            System.out.println(newFile);
            //删除
            boolean delete = file.delete();
            System.out.println(delete);
            //遍历打印
            File file1 = new File("C:\\Users\\hzw\\Desktop");
            //public File[] listFiles()
            File[] files = file1.listFiles();
            for (File file2 : files) {
                System.out.println(file2.getName());
            }
            System.out.println();
            //public String[] list()
            String[] list = file1.list();
            for (String s : list) {
                System.out.println(s);
            }
        }
    }
  • 总结:
    • File对象可不可以描述文件夹?Java中的相对路径有什么规则?
    • 在程序中一个File类对象可以代表一个文件或目录
    • Java中的相对路径体系和我们日常所见的文件系统相对路径体系有较大的区别:
      • 如果以路径以“/”或“\”开头,则相对路径的根为当前项目所在磁盘的根目录(Unix没有磁盘分区的概念,因此直接使用/,即文件系统的根作为相对路劲的根)
      • 如果不以“/”开头则相对路径的根为项目根目录,而不是当前类所在目录
      • 类从属于某个包之后,类文件实际是位于项目中的某个子文件夹中的,如com.chinasoft.Hello这个类是位于项目中的com\chinasofti子文件夹中
      • 如果在Hello类中构建一个File对象:FIle f = new File(“icss/chinasofti.txt”),那么这个文件位于项目根目录的icss子文件中,跟当前类自己的位置无关
  • 课堂练习
  • 打印某文件夹下所有文件的路径(包括子孙后代文件夹下的文件)
import java.io.File;
import java.io.IOException;

public class TestFile1 {
    public static void main(String[] args) throws IOException {
        File file = new File("writerData.txt");
        //创建
        boolean newFile = file.createNewFile();
        System.out.println(newFile);
        //删除
        boolean delete = file.delete();
        System.out.println(delete);
        //遍历打印
        File file1 = new File("C:\\Users\\hzw\\Desktop");
        //public File[] listFiles()
        File[] files = file1.listFiles();
        for (File file2 : files) {
            System.out.println(file2.getName());
        }
        System.out.println();
        //public String[] list()
        String[] list = file1.list();
        for (String s : list) {
            System.out.println(s);
        }
    }
}

IO流

1.IO流的概念与作用

1.1 IO流是什么

  • I(Input)输入,O(Out)输出

1.2 IO流的作用

  • 数据在各个设备之间的传输,是通过流的方式完成的

1.3 IO流分类

  • 根据流动方向的不同,流分为输入流和输出流(相对于内存,输入和输出)

  • 根据流的格式不同,流分为字节流和字符流

    • 程序中的输入和输出都是以流的形式保存的,流中保存的实际上全是字节文件。

    • 所有文件的存储都是字节(byte)来存储,在磁盘上保留的并不是文件的字符,而是先把字符编码成字节,再存储这些字节到硬盘上,在读取时也是一个一个的读取以形成序列

  • 根据流的功能不同,又分为节点流和处理流
    • 节点流:可以从某节点读数据或向某节点写数据的 
    • 处理流:对已存在的流的连接和封装,实现更为丰富的流数据处理,提高流读写效率

2.IO流的体系结构

2.1 字节流的抽象父类

  • InputStream字节输入流, OutputStream字节输出流

  • 派生出来的子类名称都是以其父类名作为子类名的后缀

    • 如:InputStream的子类FileInputStream

2.2 字符流的抽象父类

  • Reader 字符输入流, Writer字符输出流

  • 派生出来的子类名称都是以其父类名作为子类名的后缀

    • 如:Reader的子类FileReader

2.3 Java中IO流的体系结构

2.3.1 Java中IO流的体系结构

2.3.2 InputStream基础体系

2.3.3 OutputStrean基础体系

2.3.4 Reader基础体系

2.3.5 Writer基础体系

3.字符的输入输出流

3.1 Writer抽象类

  • Writer 类是所有字符输出流的父类
  • Writer抽象类里的方法

  • 由于Writer是抽象类不能创建对象,所以用它子类来完成写入字节的操作

3.2 FileWriter类

  • FileWriter类是Writer的子类,是文件写入流,以字符流的形式对文件进行写操作,其构造方法有5种重载,以下是常用的4种:

  • FileWriter(File file,boolean append):如果 append 的值为 true,则将字节写入文件末尾,而不是写入文件开始处。
  • FileWriter 类的创建不依赖于文件存在与否,如果关联文件不存在,则会自动生成一个新的文件。
  • 在创建文件之前,FileWriter 将在创建对象时打开它作为输出。如果试图打开一个只读文件,将引发一个 IOException 异常。
  • 在创建 FileWriter 对象时可能会引发 IOException 或 SecurityException 异常,因此需要使用 try catch 语句捕获该异常。
  • 换行符

    • 不同操作系统换行符:

      • windows下的文本文件换行符:\r\n

      • linux/unix下的文本文件换行符:\n

      • Mac下的文本文件换行符:\r

    • 要用System.getProperty(“line.separator”)代替 固定格式的换行符

      • 具备平台无关性 ; 一次编写,到处运行 ; 更保险

  • 案例
    /*
      Writer类是所有字符输出流的父类
    */
    import java.io.FileWriter;
    import java.io.IOException;
    /**
     * 字符文件输出流   FileWriter
     */
    public class FileWriterTest {
        //定义常量,保存换行符
        private static final String LIN_SEPARATOR = System.getProperty("line.separator");
        
        public static void main(String[] args) {
            // public FileWriter(String fileName, boolean append) throws IOException {}
            FileWriter wr = null;
            try {
                ////append参数 表示是否追加,true追加 false 覆盖
                wr = new FileWriter("writerData1.txt", false);
                //显示ASCII码
                wr.write(89);/*Y*/
                wr.write(74);/*J*/
                wr.write(LIN_SEPARATOR);
                //wr.write(97+LIN_SEPARATOR);
                wr.write("175269588" + LIN_SEPARATOR);
                //写入字符串的某一部分
                wr.write("SEVENTEEN", 1, 3);/*EVE*/
                //public void write(String str, int off, int len) throws IOException {}
                wr.write(LIN_SEPARATOR);
                //public void write(char cbuf[]) throws IOException {}
                wr.write(new char[]{'c', 'a', 'r'});/*car*/
                //刷新缓冲区,数据立刻写入文件
                wr.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (wr != null) {
                    try {
                        //关闭FileWriter对象
                        wr.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

3.3 Reader抽象类

  • Reader 类是所有字符流输入类的父类
  • Reader抽象类里的方法

  • 由于Reader是抽象类不能创建对象,所以用它子类来完成写入字节的操作

3.4 FileReader类

  • FileReader类是Reader的子类,文件读取流,允许以字符流的形式对文件进行读操作,其构造方法有3种重载方式,以下是常用的2种:

  • 案例:

    /*
      Reader 类是所有字符流输入类的父类
    */
    import java.io.FileReader;
    import java.io.IOException;
    /**
     * 字符文件输入流  FileReader
     */
    public class FileReaderTest {
        public static void main(String[] args) {
            readData1();
            readData2();
        }
        //自定义长度读取,public int read(char cbuf[]) throws IOException{}
        private static void readData1() {
            FileReader fr = null;
            try {
                //创建FileReader对象
                fr = new FileReader("writerData.txt");
                //定义数组
                char[] buffer = new char[24];
                //每次读到数据的数量
                int num;
                //把流中的数据循环到数组缓存中
                while ((num = fr.read(buffer)) != -1) {/*-1 : 数据读完*/
                    //数组缓存中数据变成字符串
                    String s = new String(buffer, 0, num);
                    // public String(char value[], int offset, int count) {}
                    System.out.println(s);
                }
                System.out.println("读取完毕");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (fr != null) {
                    try {
                        fr.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        //不推荐,一次读一个字符 public int read() throws IOException {}
        private static void readData2() {
            FileReader fr = null;
            try {
                fr = new FileReader("writerData.txt");
                int ch;
                //每次读入一个字符(fr.read()返回值是字符的编码值)
                while ((ch = fr.read()) != -1) {/*-1 : 数据读完*/
                    System.out.print((char) ch);
                }
                System.out.println("读取完毕");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (fr != null) {
                    try {
                        fr.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

3.5 FileReader与FileWriter实现文件的复制

  • 案例

    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class FileReaderAndFileWriterCopyTest {
        public static void main(String[] args) {
            copyFile();
        }
        /**
         * 利用FileReader.read(char[] ch)方法读取原始文件的数据
         * 利用FileWriter.write(char[] ch)方法向新文件中写数据
         */
        public static void copyFile() {
            FileReader fr = null;
            FileWriter fw = null;
            try {
                fr = new FileReader("writerData.txt");
                fw = new FileWriter("copy.txt", true);
                int num;
                char[] buffer = new char[8];
                //边读边写
                while ((num = fr.read(buffer)) != -1) {
                    //写入数据到流中
                    fw.write(buffer, 0, num);
                }//刷新,把缓冲区的数据写入文件中
                fw.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (fr != null) {
                    try {
                        fr.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fw != null) {
                    try {
                        fw.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

3.6 BufferedWriter类

  • BufferedWriter 类:为其他字符输出流提供写缓冲区。
    • 辅助其他字符输出流,带有缓冲区,可以先将一批数据写入缓冲区。
    • 当缓冲区满了以后,再将缓冲区的数据一次性写到字符输出流。
    • 目的是为了提高数据的写效率。
  • BufferedWriter类里有一个方法要注意

  • 案例

    import java.io.BufferedWriter;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class BufferedWriterTest {
        public static void main(String[] args) {
            FileWriter fw = null;
            BufferedWriter bw = null;
            try {
                fw = new FileWriter("bufferedWriter.txt");
                bw = new BufferedWriter(fw);
                for (int i = 0; i < 4; i++) {
                    bw.write("carat" + i);
                    //行分隔符号(换行)
                    bw.newLine();
                }
                bw.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (fw != null) {
                    try {
                        fw.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (bw != null) {
                    try {
                        bw.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

3.7 BufferedReader类

  • BufferedReader 类:为其他字符输入流提供读缓冲区。
  • BufferedReader类里有一个方法要注意

  • 案例

    package com.tjetc.reader;
    
    import java.io.*;
    
    public class BufferedReaderTest {
        public static void main(String[] args) {
            FileReader fr = null;
            BufferedReader br = null;
            try {
                fr = new FileReader("bufferedWriter.txt");
                br = new BufferedReader(fr);
                String str;
                //readLine()读取一行,返回字符串,如果返回null,说明数据已读完
                while ((str = br.readLine()) != null) {
                    System.out.println(str);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (fr != null) {
                    try {
                        fr.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (br != null) {
                    try {
                        br.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    /*
    carat0
    carat1
    carat2
    carat3
    */

3.8 BufferedWriter与BufferedReader实现文件的复制

  • 案例

    import com.tjetc.IOUtils;
    import java.io.*;
    
    /**
     * BufferedWriter 与 BufferedReader 实现文件的复制
     */
    public class BufferedReaderWriterTest {
        public static void main(String[] args) {
            FileReader fr = null;
            FileWriter fw = null;
            BufferedReader br = null;
            BufferedWriter bw = null;
            try {
                fr = new FileReader("writerData.txt");
                fw = new FileWriter("jinng.txt");
                br = new BufferedReader(fr);
                bw = new BufferedWriter(fw);
                //边读边写
                String str = br.readLine();
                while (str != null) {
                    bw.write(str);
                    //换行
                    bw.newLine();
                    //读取一行
                    str = br.readLine();
                }
                bw.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                //封装重复的方法到一个类中
                IOUtils.close(bw);
                IOUtils.close(br);
                IOUtils.close(fw);
                IOUtils.close(fr);
            }
        }
    }
  • 封装的IOUtils类
    import java.io.IOException;
    import java.io.Reader;
    import java.io.Writer;
    public class IOUtils {
        public static void close(Writer w) {
            if (w != null) {
                try {
                    w.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        public static void close(Reader r) {
            if (r != null) {
                try {
                    r.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

4.字节的输入输出流

4.1 OutputStream类

  • OutputStream它不仅可以写入字节,字符,还可以写入图片等媒体文件

  • 由于OutputStream是抽象类不能创建对象,所以用它子类来完成写入字节的操作

4.2 FileOutputStream类

  • 用OutputStream的子类java.io.FileOutputStream向文件中写入字节

  • FileOutputStream类的构造方法有5种重载方式,以下是常用的4种

  • 案例

    import java.io.FileOutputStream;
    import java.io.IOException;
    public class FileOutputStreamTest {
        public static void main(String[] args) {
            FileOutputStream fos = null;
            //创建 FileOutputStream 对象
            try {
                fos = new FileOutputStream("data.txt");
                //void write(int b)
                fos.write(98);
                //void write(byte b[])
                fos.write("abc".getBytes());
                //void write(byte b[], int off, int len)
                fos.write("171717".getBytes(), 1, 3);
                //字节流不用刷新,FileOutputStream虽然也有flush方法,但方法里是空的
                fos.flush();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    /*data文件内的内容
     * babc717
     */

4.3 InputStream类

  • InputStream它不仅可以读取字节,字符,还可以读取图片等媒体文件

  • 注意:在使用 mark() 方法和 reset() 方法之前,需要判断该文件系统是否支持这两个方法,以避免对程序造成影响。
  • 由于IntputStream是抽象类不能创建对象,所以用它子类来完成写入字节的操作

4.4 FileInputStream类

  • 访问文件中的一个字节、一批字节或整个文件
  • FileOutputStream类的构造方法有3种重载方式,以下是常用的2种

    构 造 方 法 说 明
    FileInputStream(File file) throws FileNotFoundException 使用File对象创建文件输入流对象,如果文件打开失败,将抛出异常
    FileInputStream(String name) throws FileNotFoundException 使用文件名或路径创建文件输入流对象,如果文件打开失败,将抛出异常
  • 有一个 data.txt 文件,下面使用 FileInputStream 类读取并输出该文件的内容。具体代码如下:

    import java.io.FileInputStream;
    import java.io.IOException;
    public class FileInputStreamTest {
        public static void main(String[] args) {
            fileInputStreamByReadChar();
            fileInputStreamByRead();
        }
        /**
         * public int read(byte b[]) throws IOException {}
         * 从输入流中读取若干字节,并把它们保存到参数 b 指定的字节数组中。
         * 该方法,返回读取的字节数。
         * 如果返回 -1,则表示已经到了输入流的末尾
         */
        public static void fileInputStreamByReadChar() {
            FileInputStream fis = null;
            try {
                fis = new FileInputStream("data.txt");
                byte[] b = new byte[1024];
                int num = fis.read(b);
                while (num != -1) {
                    String s = new String(b, 0, num);
                    System.out.println(s);/*babc717*/
                    num = fis.read(b);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        /**
         * public int read() throws IOException {}
         * 从输入流中读取一个 8 位的字节,并把它转换为 0~255 的整数,最后返回整数。
         * 如果返回 -1,则表示已经到了输入流的末尾。
         */
        public static void fileInputStreamByRead() {
            FileInputStream fis = null;
            try {
                fis = new FileInputStream("data.txt");
                int num = fis.read();
                while (num != -1) {
                    // 读一个打印一个
                    System.out.print((char) num);/*babc717*/
                    num = fis.read();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

4.5 FileInputStream与FileOutputStream实现文件复制

  • 案例

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class FileInputOutStreamTest {
        public static void main(String[] args) {
            FileOutputStream fos = null;
            FileInputStream fis = null;
            try {
                //可以复制图片、音频、视频等等
                fis = new FileInputStream("1.jpg");
                fos = new FileOutputStream("2.jpg");
                /*fis = new FileInputStream("data.txt");
                fos = new FileOutputStream("data1.txt");*/
                byte[] b = new byte[1024];
                int len = 0;
                //边读边写
                while ((len = fis.read(b)) != -1) {
                    fos.write(b, 0, len);
                }
                fos.flush();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

4.6 BufferedOutputStream类

  • BufferedOutputStream类里有一个方法要注意

  • 案例

    import com.tjetc.IOUtils;//自己写的封装类
    import java.io.BufferedOutputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class BufferedOutputStreamTest {
        public static void main(String[] args) {
            FileOutputStream fos = null;
            BufferedOutputStream bos = null;
            try {
                fos =new FileOutputStream("data2.txt");
                //BufferedOutputStream构造方法需要传入OutStream流对象
                bos = new BufferedOutputStream(fos);
                bos.write(97);/*a*/
                bos.write("abc".getBytes());/*abc*/
                bos.write("0123456".getBytes(),2,5);/*23456*/
                bos.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                IOUtils.close(bos);
                IOUtils.close(fos);
            }
        }
    }
    /*
    aabc23456
    */

4.7 BufferedInputStream类

  • BufferedInputStream类里有一个方法要注意

  • 案例

    import com.tjetc.IOUtils;//自己写的封装类
    import java.io.BufferedInputStream;
    import java.io.FileInputStream;
    import java.io.IOException;
    
    public class BufferedInputStreamTest {
        public static void main(String[] args) {
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                fis = new FileInputStream("data2.txt");
                //BufferedInputStream构造方法需要传入InputStream流对象
                bis = new BufferedInputStream(fis);
                int len = 0;
                byte[] b = new byte[1024];
                while ((len = bis.read(b)) != -1) {
                    System.out.println(new String(b, 0, len));
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                IOUtils.close(bis);
                IOUtils.close(fis);
            }
        }
    }
    /*
    aabc23456
    */

4.8 BufferedInputStream与BufferedOutputStream实现文件复制

  • 案例

    import com.tjetc.IOUtils;
    import java.io.*;
    public class BufferedInputOutStreamTest {
        public static void main(String[] args) {
            FileInputStream is = null;
            FileOutputStream os = null;
            BufferedOutputStream bos = null;
            BufferedInputStream bis = null;
            try {
                //is = new FileInputStream("1.jpg");
                is = new FileInputStream("data.txt");
                bis = new BufferedInputStream(is);
                //os = new FileOutputStream("4.jpg");
                os = new FileOutputStream("data3.txt");
                bos = new BufferedOutputStream(os);
                int len = 0;
                byte[] b = new byte[1024];
                while ((len = bis.read(b)) != -1) {
                    bos.write(b);
                    bos.flush();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                IOUtils.close(bos);
                IOUtils.close(bis);
                IOUtils.close(os);
                IOUtils.close(is);
            }
        }
    }
    /*data3.txt文件中的内容:
    babc717
    */

5.System的标准输入输出流

5.1 输入和输出流

  • 程序对应的基本输入为键盘输入,基本输出为显示器输出。

  • Java中,System类的in和out两个成员代表了基本输入输出的抽象

  • System.in:

    • System.in是InputStream, 标准输入流, 默认可以从键盘输入读取字节数据

    • 注意:System.in流是无需关闭的
    • 案例
      import java.io.BufferedInputStream;
      import java.io.IOException;
      public class SystemInTest {
          public static void main(String[] args) {
              BufferedInputStream bis = null;
              System.out.println("输入数据:");
              //创建BufferedInputStream对象,传入的参数是System.in的InputStream(接收键盘输入的数据)
              try {
                  //System.in无需关闭
                  bis = new BufferedInputStream(System.in);
                  //定义字节数组
                  byte[] buffer = new byte[200];
                  int len;
                  //循环读取数据并打印到控制台
                  while ((len = bis.read(buffer)) != -1) {
                      String s = new String(buffer, 0, len);
                      System.out.println("您输入的数据为:" + s);
                  }
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
      /*
      输入数据:
      aaa
      您输入的数据为:aaa
      
      bb
      您输入的数据为:bb
      
      c
      您输入的数据为:c
      */
  • System.out:
    • System.out是PrintStream, 标准输出流, 默认可以向控制台中输出字符和字节数据

    • PrintStream继承了OutputStream

    • 案例
      import com.tjetc.IOUtils;
      import java.io.BufferedOutputStream;
      import java.io.IOException;
      
      public class SystemOutTest {
          public static void main(String[] args) {
              //创建BufferedOutputStream对象
              BufferedOutputStream bos = null;
              try {
                  //传入的参数System.out是PrintStream,输出控制台字符和字节
                  bos = new BufferedOutputStream(System.out);
                  bos.write("SEVENTEEN".getBytes());
              } catch (IOException e) {
                  e.printStackTrace();
              } finally {
                  IOUtils.close(bos);
              }
          }
      }
      /*
      SEVENTEEN
      */

5.2 Scanner类

 

  • Scanner类位于java.util包中,不在java.io包中,不属于IO流

  • Scanner是一个工具类,主要目标是简化文本的扫描,最常使用此类获取控制台输入,Scanner获取控制台输入的步骤:

    • 使用控制台输入创建Scanner对象

      Scanner scanner=new Scanner(System.in);
  • 调用Scanner中的nextXXX方法,获得需要的数据类型

    例如:next、 nextLine、nextInt、nextByte等

    import java.util.Scanner;
    public class ScannerTest {
        public static void main(String[] args) {
            //System.in是InputStream 字节输入流,可以读取键盘输入的数据
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入数据");
            while (true) {
                String next = sc.next();
                //"exit".equals(next)     next.equals("exit")
               /* 如果next为null
               "exit".equals(next)  返回false
               next.equals("exit") 报空指针异常
              */
                if ("exit".equals(next)) {
                    System.out.println("再见!!!");
                    break;
                }
                System.out.println("您输入的数据是:" + next);
            }
        }
    }
    /*
    请输入数据
    111
    您输入的数据是:111
    111
    您输入的数据是:111
    exit
    再见!!!
    */

6.字节字符转换流

  • 转换流:以将一个字节流转换为字符流,也可以将一个字符流转换为字节流

  • 字节字符转换流位于java.io包

6.1 OutputStreamWriter类

  • OutputStreamWriter:可以将输出的字符流转换为字节流的输出形式

  • 字符流转换成字节流图解

  • 案例

    import com.tjetc.IOUtils;
    import java.io.*;
    public class OutputStreamWriterTest {
        public static void main(String[] args) {
            FileOutputStream fos = null;
            OutputStreamWriter osw = null;
            BufferedWriter bw = null;
            try {
                fos = new FileOutputStream("myData.txt");
                osw = new OutputStreamWriter(fos, "utf-8");
                bw = new BufferedWriter(osw);
                //BufferedWriter对象 把字符串写入流中(写入字符流  -> 转换流 -> 字节流 —> 文件中)
                bw.write("carat");
                //flush
                bw.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                //关闭流对象
                IOUtils.close(bw);
                IOUtils.close(osw);
                IOUtils.close(fos);
            }
        }
    }
    /*myData.txt文件中的内容:
    carat
    */

6.2 InputStreamReader类

  • InputStreamReader:将输入的字节流转换为字符流输入形式。

  • 字节流转换成字符流图解

  • 案例

    import com.tjetc.IOUtils;
    import java.io.*;
    public class SystemReaderTest {
        public static void main(String[] args) {
            //字节输入流对象
            InputStream in = System.in;
            InputStreamReader isr = null;
            BufferedReader br = null;
            System.out.println("请输入数据:");
            try {
                isr = new InputStreamReader(in, "utf-8");
                br = new BufferedReader(isr);
                //BufferedReader对象循环的读取一行数据
                while (true) {
                    String s = br.readLine();
                    if ("exit".equals(s)) {
                        System.out.println("ByeBye");
                        break;
                    }
                    System.out.println("您输入的数据为:" + s);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                IOUtils.close(br);
                IOUtils.close(isr);
            }
        }
    }
    /*
    请输入数据:
    carat
    您输入的数据为:carat
    SEVENTEEN
    您输入的数据为:SEVENTEEN
    exit
    ByeBye
    */

7.随机访问文件流

  • 随机流(RandomAccessFile):此类的实例支持对随机访问文件的读取和写入

  • 位于java.io包

  • 特点

    • 该对象即能读也能写,一个对象就搞定

    • 该对象内部维护了一个大型 byte 数组,光标或索引在该数组任意位置读取或写入任意数据

    • 可以通过getFilePointer方法获得光标的位置和通过seek方法设置光标位置

    • 该对象将字节输入流和输出流进行了封装

    • 该对象源或目的,只能文件,通过下面的构造方法就可以看出

  • 构造方法

  • 随机流的方法有很多

  • 案例

    import java.io.IOException;
    import java.io.RandomAccessFile;
    //在randomData.txt 写入 我在大国很安全
    public class TestRandomAccessFile {
        public static void main(String[] args) throws IOException {
            //(String name/File file, String mode) ; mode 可选 "r" "w"  "rw"
            RandomAccessFile raf = new RandomAccessFile("randomData.txt", "rw");
            byte[] buffer = new byte[20];
            //跳过4个汉字之后读取文件数据
            raf.seek(3 * 4);
            //读取文件数据,把数据存到buffer,从buffer的0位置开始存储,存12个字节
            raf.read(buffer, 0, 12);
            //把buffer中的数据转换成字符串,buffer中从0位置开始,取出12个字节
            String s = new String(buffer, 0, 12);
            System.out.println(s);/*很安全*/
    
            //跳过两个字节之后写入数据
            raf.seek(2 * 3);
            //写数据 注意:写的数据会覆盖对应位置的原数据
            raf.write("中".getBytes());
        }
    }
    /*randomData文件中的内容:
    我在中国很安全
    */

8.字节数组流

  • 字节数组流:提供了针对于字符数组 byte [] 的标准的IO操作方式

  • 位于java.io包

  • ByteArrayInputStream 和 ByteArrayOutputStream

    • ByteArrayInputStream将会给一个byte buf[] 提供标准的IO操作方式

    • ByteArrayOutputStream将数据写入到内部的字节数组中

    •  ByteArrayOutputStream写入的属于内存数据,不涉及任何资源,所以不需要close

  • 案例

    import java.io.*;
    
    public class TestByteArrayOutputAndInputStream {
        public static void main(String[] args) {
            byte[] buffer = getBuffer();
            printBuffer(buffer);
        }
    
        private static byte[] getBuffer() {
            byte[] buffer = null;
            ByteArrayOutputStream baos = null;
            BufferedOutputStream bos = null;
            try {
                baos = new ByteArrayOutputStream();
                bos = new BufferedOutputStream(baos);
                //写入数据到ByteArrayOutputStream对象baos中(内存中)
                bos.write("SEVENTEEN".getBytes());
                bos.flush();
                //baos转换成数据赋值给数据buffer存储中
                buffer = baos.toByteArray();
                /*public synchronized byte toByteArray()[] {
                    return Arrays.copyOf(buf, count);
                }*/
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (bos != null) {
                        bos.close();
                    }
                    if (baos != null) {
                        bos.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return buffer;/*buffer:{83,69,86,69,78,84,69,69,78}*/
        }
        private static void printBuffer(byte[] buffer){
            ByteArrayInputStream bais = null;
            BufferedInputStream bis =null;
            byte[] b =new byte[buffer.length];
            try{
                bais = new ByteArrayInputStream(buffer);
                bis = new BufferedInputStream(bais);
                //读取数据到b数组中
                bis.read(b);
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    bis.close();
                    bais.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(new String(b));/*SEVENTEEN*/
        }
    }
这篇关于Java-文件、IO流的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!