A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 13333114253 中级黑马   /  2018-11-26 15:43  /  664 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 13333114253 于 2018-12-3 10:24 编辑

上一个总结:
[石家庄校区]JAVA_线程_Lambda表达式_File类_IO流
字节输入流: InputStream和FileInputStream
java.io.InputStream抽象类: 字节输入流 (顶层类)
        // 常用成员方法
        void close(): 释放资源
        // 读数据的方法
        int read(): 一次读一个字节
                读到文件末尾返回-1 (返回int也是为了代码编写方便)
        int read(byte[] b): 一次读一个字节数组
                读到的字节存放在参数中的字节数组中, 返回int值是本次读到的字节的个数. 读到文件末尾返回-1

java.io.FileInputStream类: 文件字节输入流
        // 构造方法
        FileInputStream(String name): 使用文件路径创建文件字节输入流
        FileInputStream(File file): 使用File对象创建文件字节输入流

        构造方法的作用:
                1. 创建FileInputStream对象
                2. 将FileInputStream对象指向磁盘上的文件
字节输入流: 一次读取一个字节
Java程序从文件读取数据的原理:
        Java程序 -> JVM虚拟机 -> OS(操作系统) -> OS调用读取的方法 -> 读取磁盘文件数据
        
java.io.InputStream抽象类: 字节输入流 (顶层类)
        int read(): 一次读一个字节
                读到文件末尾返回-1 (返回int也是为了代码编写方便)
字节输入流: 一次一个字节
[Java] 纯文本查看 复制代码
FileInputStream fis = new FileInputStream("模块名\\文件名");
    // 一次读一个字节:
    int by;   // int变量用来存储每次读到的数据
    while ((by = fis.read()) != -1) {
        System.out.print((char)by);  // 不要换行, 文件中自带换行的byte
    }
 
    fis.close();

字节输入流: 一次一个字节数组
java.io.InputStream抽象类: 字节输入流 (顶层类)
        int read(byte[] b): 一次读一个字节数组
                参数 byte[] b 作用: 存储每次读到的字节, 起到缓冲作用
                返回值作用: 每次读到的字节个数, 读到文件末尾返回-1

[Java] 纯文本查看 复制代码
// 示例代码
FileInputStream fis = new FileInputStream("模块名\\文件名");
byte[] bytes = new byte[1024];  // 定义字节数组, 用于保存每次读取到的数据
int len;                        // 定义int变量, 用于保存每次读取到的长度
while ((len = fis.read(bytes)) != -1) {
    String s = new String(bytes, 0, len); // 将读取到的字节转换为字符串, 读到多少个就转换多少个
    System.out.print(s);
}
 
fis.close(); // 释放资源

字节流复制图片文件
文件复制的步骤:
        1.创建一个字节输入流对象,构造方法中绑定要读取的数据源
        2.创建一个字节输出流对象,构造方法中绑定要写入的目的地
        3.使用字节输入流对象中的方法read读取文件
        4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中
        5.释放资源
[Java] 纯文本查看 复制代码
// 创建输入流和输出流
    FileInputStream fis = new FileInputStream("c:\\1.jpg");   //输入流指向要读的数据源文件
    FileOutputStream fos = new FileOutputStream("d:\\1.jpg"); //输出流指向要写的目的地文件
    // 一次读写一个字节数组
    byte[] bytes = new byte[1024];
    int len = 0;
    while((len = fis.read(bytes))!=-1){
        fos.write(bytes,0,len);
    }
    // 释放资源
    fos.close();
    fis.close();

字节流读取中文问题
GBK编码中, 一个汉字占用2个byte
UTF-8编码中, 一个汉字占用3个byte
字符流字符输入流: Reader和FileReader

注意: 字符流只能读写"文本文件"

java.io.Reader抽象类: 字符输入流 (顶层)
        // 常用成员方法
        void close() :关闭此流并释放与此流相关联的任何系统资源
        // 读
        int read(): 一次读一个字符char, 返回读到的字符.
            读到文件末尾返回-1  (返回int为了代码编写方便)
        int read(char[] cbuf): 一次读取一个字符数组char[]
                返回读取的字符个数. 读到文件末尾返回-1


java.io.FileReader类: 文件字符输入流
        // 构造方法
        FileReader(File file): 根据File对象创建文件字符输入流
        FileReader(String fileName): 根据File对象创建文件字符输入流

        构造方法的作用:
                1. 创建FileReader对象
                2. 将FileReader对象指向磁盘上的文件
字符输入流: 2种方式读取文本文件
java.io.Reader抽象类: 字符输入流 (顶层)
        int read(): 一次读一个字符char, 返回读到的字符.
            读到文件末尾返回-1  (返回int为了代码编写方便)
        int read(char[] cbuf): 一次读取一个字符数组char[]
                返回读取的字符个数. 读到文件末尾返回-1

java.lang.String类:
       String(char[] value): 将char数组转换为String
        String(char[] value, int offset, int count): 将char数组的一部分转换为String

[Java] 纯文本查看 复制代码
FileReader fr = new FileReader("a.txt");
 
// 一次读一个字符
int ch;  // 定义变量保存每次读到的字符
while ((ch = fr.read()) != -1) {
    System.out.print((char)ch);
}
 
// 一次读一个字符数组
char[] cs = new char[1024];
int len;
while ((len = fr.read(cs)) != -1) {
    String s = new String(cs, 0, len);
    System.out.print(s);
}
 
// 释放资源
fr.close();

字符输出流: Writer和FileWriter

java.io.Writer抽象类: 字符输出流 (顶层类)   'a''b'  缓冲区    97 98
        // 常用成员方法
        abstract void close(): 刷新缓冲区并释放资源
        abstract void flush() :刷新缓冲区

[Java] 纯文本查看 复制代码
FileWriter fw = new FileWriter("09_IOAndProperties\\d.txt");
    fw.write(97);  // int ch 用int值代表char
    //fw.flush();
    fw.close();

字符输出流: flush与close区别
区别:
        flush(): 刷新缓冲区 (将数据从内存中写入到磁盘)
        close(): 刷新缓冲区, 并释放资源. 关闭流后不能再用同一个流对象操作
          flush()可以省略, 只用close()来刷新并释放资源
字符输出流: 其他方法
        void write(int c): 写一个字符 (int类型为了代码编写方便)
        void write(char[] cbuf): 写一个字符数组
        abstract void write(char[] b, int off, int len): 写一个字符数组的一部分
        void write(String str): 写一个字符串
        void write(String str, int off, int len): 写一个字符串的一部分

        注意: write()方法只是将数据写到内存缓冲区, 最后必须调用flush()或close()才能将数据真正写入磁盘

java.io.FileWriter类: 文件字符输出流
        // 构造方法
       FileWriter(File file): 通过File对象创建文件字符输出流
        FileWriter(String fileName): 通过文件路径创建文件字符输出流

        作用:
                1. 创建FileWriter对象
                2. 根据构造方法中的路径, 在磁盘上创建文件 ("如果文件已存在, 则清空文件内容")
                3. 将FileWriter对象指向磁盘上的文件
字符输出流: 一次写一个字符
void write(int c): 写一个字符 (int类型为了代码编写方便)
字符输出流: 续写, 换行
FileWriter中带有续写功能的构造:
        FileWriter(File file, boolean append): 通过File对象创建流. 第二个参数为true可以续写
        FileWriter(String fileName, boolean append): 通过文件路径创建流. 第二个参数为true可以续写

IO异常处理IO流操作中的异常处理
    IO流的标准格式:
[Java] 纯文本查看 复制代码
FileWriter fw = null;
    try {
        //IO流对象的创建, 操作等代码
        fw = new FileWriter("d:\\09_IOAndProperties\\g.txt", true);
        for (int i = 0; i <10 ; i++) {
            fw.write("HelloWorld"+i+"\r\n");
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 释放资源
        if(fw != null){
            try {
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

Properties集合Properties存储数据和遍历
Properties双列集合:
        键和值都是 String 类型

java.util.Properties类: 属性集, 属于Map的双列集合, 继承自Hashtable
        // 构造方法
        Properties(): 创建一个Properties集合
        // 可以使用Map接口中的方法
        // 特有成员方法
        Object setProperty(String key, String value): 保存/替换键值对
        String getProperty(String key): 通过键获取值. 键不存在返回null
        Set<String> stringPropertyNames(): 返回键的集合
        void store(OutputStream out, String comments): 将集合用字节流写入文件(不能中文),并写入注释
        void store(Writer writer, String comments): 将集合用字符流写入文件(可以中文),并写入注释
        void load(InputStream inStream): 从配置文件中通过字节流加载数据到Properties集合(不能读中文)
        void load(Reader reader): 从配置文件中通过字符流加载数据到Properties集合(可以读中文)
Properties: store()存储数据到文件
Properties将数据写入到文件的方法:

        void store(OutputStream out, String comments): 将集合用字节流写入文件(不能中文),并写入注释
        void store(Writer writer, String comments): 将集合用字符流写入文件(可以中文), 并写入注释

        
使用步骤:
        1.创建Properties集合对象,添加数据
        2.创建字节输出流/字符输出流对象,构造方法中绑定要输出的目的地
        3.使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
        4.释放资源
使用Properties添加数据并写入文件
[Java] 纯文本查看 复制代码
[/b]public class Test {
    public static void main(String[] args) throws IOException {
        // 创建Properties集合对象
        Properties properties = new Properties();
 
        // 添加键值对 setProperty(String key, String value)
        properties.setProperty("赵丽颖", "168");
        properties.setProperty("迪丽热巴", "165");
        properties.setProperty("古力娜扎", "160");
 
        // 创建文件字符输出流对象
//        FileWriter fw = new FileWriter("day09\\prop.properties");
        FileWriter fw = new FileWriter("day09\\prop.txt");
 
        // 将Properties集合中的数据, 写入到文件 store()
//        properties.store(fw, "");
        properties.store(fw, null);  // 第二个参数注释, 传递null也可以, 这样就不会出现空行注释
 
        // 关闭流
        fw.close();
    }
}[b]


Properties: load()从文件加载数据到集合
Properties将数据从文件加载到集合中的方法:
  
      void load(InputStream inStream): 从配置文件中通过字节流加载数据到Properties集合(不能读中文)
        void load(Reader reader): 从配置文件中通过字符流加载数据到Properties集合(可以读中文)


使用步骤:
        1.创建Properties集合对象
        2.使用Properties集合对象中的方法load读取保存键值对的文件
        3.遍历Properties集合


加载文件数据到Properties
[Java] 纯文本查看 复制代码
[/b]public class Test {
    public static void main(String[] args) throws IOException {
        // 创建Properties集合对象
        Properties properties = new Properties();
 
        // 创建文件字符输入流对象
        FileReader fr = new FileReader("day09\\prop.properties");
 
        // 从硬盘上读取到集合: load()
        properties.load(fr);  // 方法调用完毕后, 集合里面就有键值对了
 
        // 遍历集合
        Set<String> strings = properties.stringPropertyNames();
        for (String key : strings) {
            // 通过键获取值
            String value = properties.getProperty(key);
            System.out.println(key + "=" + value);
        }
    }
}[b]

01 - 缓冲流
缓冲字节输出流: BufferedOutputStream   高效流

java.io.BufferedOutputStream类: 缓冲字节输出流
    // 构造方法
    BufferedOutputStream(OutputStream out): 使用基本流创建一个缓冲字节输出流
    BufferedOutputStream(OutputStream out, int size): 使用基本流创建一个缓冲字节输出流, 设置缓冲区大小

使用BufferedOutputStream向当前模块写入文件内容

[Java] 纯文本查看 复制代码
FileOutputStream fos = new FileOutputStream("文件路径");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
//BufferedOutputStream  bos= new  BufferedOutputStream(new FileOutputStream("文件路径"));
        bos.write("你好".getBytes());
        // bos.flush();  // 可以省略
        bos.close();

缓冲字节输入流:BufferedInputStream
java.io.BufferedInputStream类: 缓冲字节输入流
    // 构造方法
    BufferedInputStream(InputStream in): 使用基本流创建一个缓冲字节输入流
    BufferedInputStream(InputStream in, int size): 使用基本流创建一个缓冲字节输入流, 设置缓冲区大小

使用BufferedInputStream读取文件

[Java] 纯文本查看 复制代码
FileInputStream fis = new FileInputStream("文件路径");
        BufferedInputStream bis = new BufferedInputStream(fis);
        byte[] bytes = new byte[1024];
        int len;
        while ((len = bis.read(bytes)) != -1) {
        System.out.println(new String(bytes, 0, len));
    }
        bis.close();

缓冲字符输出流: BufferedWriter
java.io.BufferedWriter类:
    // 构造方法
    BufferedWriter(Writer out): 使用基本流创建一个缓冲字符输出流
    BufferedWriter(Writer out, int size): 使用基本流创建一个缓冲字符输出流, 设置缓冲区大小
    // 特有方法
    void newLine(): 写入一个换行符, 换行符自动根据当前系统确定

[Java] 纯文本查看 复制代码
 BufferedWriter bw = new BufferedWriter(new FileWriter("文件路径"));
// 循环10次写入内容和换行
        for (int i = 0; i < 10; i++) {
            // 写入内容
            bw.write("传智播客");
            // 写入换行符
            bw.newLine();
        }
        // 刷新 (可以省略)
//        bw.flush();

        // 释放资源
        bw.close();

缓冲字符输入流: BufferedReader
java.io.BufferedReader类: 缓冲字符输入流
    // 构造方法
    BufferedReader(Reader in): 使用基本流创建一个缓冲字符输入流
    BufferedReader(Reader in, int size): 使用基本流创建一个缓冲字符输入流, 设置缓冲区大小
    // 特有方法
    String readLine(): 一次读一行字符串, "不包含换行符". 读到文件末尾返回null
[Java] 纯文本查看 复制代码
BufferedReader br = new BufferedReader(new FileReader("文件路径"));[/color][/color][/font]
        // 循环读取
        String line;  // 定义String变量, 用于保存每次读到的一行字符串
        while ((line = br.readLine()) != null) {
            // 将读到的字符串打印出来, 因为字符串中不带换行符, 所以我们打印需要用println
            System.out.println(line);
        }

        // 释放资源
        br.close();

OutputStreamWriter类

java.io.OutputStreamWriter类: 输出转换流. 字符流通往字节流的桥梁
    // 构造方法
    OutputStreamWriter(OutputStream out): 使用默认编码表创建转换流
    OutputStreamWriter(OutputStream out, String charsetName): 使用指定编码表创建转换流


// 使用默认UTF-8
OutputStreamWriter o = new OutputStreamWriter(new FileOutputStream("a.txt"));
o.write("dsfdsfdsaf")

// 使用指定的GBK
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"), "GBK");
        osw.write("你") -> 查"GBK"码表 -> -1,-2 -> FileOutputStream -> a.txt文件
         写数据: 字符流 --------------------------> 字节流
InputStreamReader类
java.io.InputStreamReader类: 输入转换流. 字节流通往字符流的桥梁
    // 构造方法
    InputStreamReader(InputStream in): 使用默认编码表创建转换流
    InputStreamReader(InputStream in, String charsetName): 使用指定编码表创建转换流

   
// 使用默认UTF-8
InputStreamReader r = new InputStreamReader(new FileInputStream("a.txt"));

// 使用指定的GBK
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"), "GBK");
     '你' <- 查"GBK"码表 <- isr.read() <- -1,-2 <- FileInputStream <- a.txt文件
                         读数据: 字符流 <---------- 字节流   

例:
[Java] 纯文本查看 复制代码
public class Test {
    public static void main(String[] args) throws IOException {
        // 创建转换输入流对象, 指向GBK文件, 同时指定按照GBK来读取
        InputStreamReader isr = new InputStreamReader(new FileInputStream("day10\\我是GBK.txt"), "GBK");
        // 创建转换输出流对象, 路径填写utf8文件, 同时指定按照UTF-8来写
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("day10\\我是UTF8文件.txt"), "UTF-8");

        // 循环读写: 类似于文件复制, 一次读写一个字符
        int ch;
        while ((ch = isr.read()) != -1) {
            // 读到一个写一个
            osw.write(ch);
        }

        // 刷新缓冲区并释放资源
        osw.close();
        isr.close();
    }
}

对象序列化流: ObjectOutputStream
java.io.ObjectOutputStream类: 对象字节输出流
    // 构造方法
    ObjectOutputStream(OutputStream out)
    // 特有成员方法
    void writeObject(Object obj): 将对象写出

// 创建对象输出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("student.txt"));
// 写对象
Student s = new Student("小美女", 18);
oos.writeObject(s);
// 释放资源
oos.close();
注意:
    被读写的对象的类必须实现"java.io.Serializable"接口, 否则会抛出"NotSerializableException"
对象反序列化流: ObjectInputStream
java.io.ObjectInputStream类: 对象字节输入流
    // 构造方法
    ObjectInputStream(InputStream in)
    // 特有成员方法
    Object readObject(): 读取对象

   
// 创建对象输入流
ObjectInputStream oos = new ObjectInputStream(new FileInputStream("student.txt"));
// 读对象
Object o = oos.readObject();
Student s = (Student)o;
System.out.println(s);
// 释放资源
oos.close();
transient瞬态关键字: 避免属性序列化      如果对象的某个属性不希望被序列化, 可以使用 transient 修饰, 这样就不会被对象流写到文件中
InvalidClassException异常: 原因和解决方案        serialVersionUID序列号的作用:
    序列化操作时, 会根据类生成一个默认的 serialVersionUID 属性, 写入到文件中.

IDEA设置生成序列版本号:
Setting -> Editor -> Inspections -> Java -> Serialization issues -> 勾选Serializable class without 'serialVersionUID然后在类名上按Alt + Enter提示就会有Add 'serialVersionID' field
打印流PrintStream

PrintStream特点:
    1. 只有输出流, 没有输入流
    2. PrintStream不会抛出IOException
    3. 有特殊方法 print(), println(), 可以输出任意类型的值, 原样输出

java.io.PrintStream类: 字节打印流
   // 构造方法
    PrintStream(File file): 创建字节打印流, 输出到一个文件
    PrintStream(OutputStream out): 创建字节打印流, 输出到一个字节输出流
    PrintStream(String fileName): 创建字节打印流, 输出到一个文件路径

   
注意事项:
    如果用 write(97) 方法, 会查编码表   97 -> a
    如果用 print(97), println(97), 则原样输出  97 int -> '9''7' -> byte -> 文件 97
    System.out.println();
    PrintStream out;
   
java.lang.System类:
    // 静态方法
    static void setOut(PrintStream out): 设置System.out的输出目的地为参数的打印流

IO总结:
// 体系结构:
字节流
    |_ InputStream                 # 字节输入流
    |    |_ FileInputStream         # 专门操作文件的字节输入流
    |    |_ BufferedInputStream     # 带有缓冲区的字节输入流, 效率高
    |    |_ ObjectInputStream       # 对象输入流
    |
    |_ OutputStream                # 字节输出流
        |_ FileOutputStream        # 专门操作文件的字节输出流
        |_ BufferedOutputStream    # 带有缓冲区的字节输出流, 效率高
        |_ ObjectOutputStream      # 对象输出流
        |_ PrintStream             # 字节打印流
字符流
    |_ Reader                      # 字符输入流
    |    |_ BufferedReader          # 带有缓冲区的字符输入流, 效率高
    |    |_ InputStreamReader       # 将字节流转换为字符流输入的转换输入流
    |        |_ FileReader          # 专门操作文件的字符输入流   
    |
    |_ Writer                      # 字符输出流
        |_ BufferedWriter          # 带有缓冲区的字符输出流, 效率高
        |_ OutputStreamWriter      # 将字符流转换为字节流输出的转换输出流
        |     |_ FileWriter         # 专门操作文件的字符输出流












0 个回复

您需要登录后才可以回帖 登录 | 加入黑马