JAVA (IO流) day7.25

ok了家人们今天继续学习io流,废话不多说,我们一起看看吧

.File

1.1 File类的概述

通过 File 类与 IO 流进行搭配使用就可以通过 Java 代码将数
据从内存写入到硬盘文件 或者从硬盘文件读取到内存
中。
File 类就是文件和目录路径名的抽象表示形式。 主要用于
文件和目录的创建、查找和删除等操作。
也就是说 File 类可以表示一个文件也可以表示一个文件
夹,我们可以通过操作 File 对象提供的相关方法对它所表
示的文件 / 文件夹进行操作。

1.2 File类的构造方法

public File(String pathname) :通过将给定的 路径名
字符串 转换为抽象路径名来创建新的 File 实例。
public File(String parent, String child) :从 父路径名
字符串和子路径名字符串 创建新的 File 实例。
public File(File parent, String child) :从 父抽象路径
名和子路径名字符串 创建新的 File 实例。

1.3 File类的判断方法

public boolean exists() :此 File 表示的文件或目录是
否实际存在。
public boolean isFile() :此 File 表示的是否为文件。
public boolean isDirectory() :此 File 表示的是否为
目录。

1.4 File类的获取方法

public String getAbsolutePath() :返回此 File 的绝对
路径名字符串。(带盘符的路径)
public String getPath() :将此 File 转换为路径名字符
串。 (获取的是 封装路径)
public String getName() :返回由此 File 表示的文件或
目录的名称。
public long length() :返回由此 File 表示的文件的长
度。 不能获取目录的长度。

1.5 相对路径和绝对路径

绝对路径:从盘符开始的路径,这是一个完整的路
径。
相对路径:在 IDEA 中,是相对于 idea 中的 project
路径!

1.6 File类的创建和删除方法

public boolean createNewFile() :当且仅当具有该名
称的文件尚不存在时,创建一个新的空文件。
public boolean delete() :删除由此 File 表示的文件或
目录。
public boolean mkdir() :创建一个单级文件夹
public boolean mkdirs() :创建一个多级文件夹。

 1.7 File类的遍历方法

public String[] list() :返回一个 String 数组,存储的是
File 目录中所有的子文件或子目录的名称。
public File[] listFiles() :返回一个 File 数组,存储的是
File 目录中所有的子文件或子目录的路径的 File 对象。

.方法递归

递归要有出口 ( 结束方法 ), 否则会报栈内存溢出错误
StackOverflowError
递归次数不宜过多
2.1  递归获取文件夹下所有文件
/**
* 需求:设计一个方法,可以遍历某个文件夹下所有的文件 包含子目录中的文件 
* 并把文件的绝对路径打印出来 
*/

public class DemoTest { 
    public static void main(String[] args) throws IOException {
        File dir = new File("java_0709\\A");
        printDir(dir); 
}
public static void printDir(File dir){ 
//被传入的文件夹 
        //获取 当前dir下所有的文件和文件夹
        File[] files = dir.listFiles(); 
        //进行遍历 拿到每个文件和文件夹 对象file
        for (File file : files) {
             //file是文件还是文件夹 都有 
            if(file.isFile()){
// 文件 
            System.out.println("文件的路 径是:"+file.getAbsolutePath());
            }else {
             //file是一个文件夹 怎么办? 继 续找' 
            printDir(file);
            }
        }
    }
}

三.IO概述

1.1 IO流介绍

学习 IO 流的目的:
        1,将数据写到文件中,实现数据永久化存储
        2,把文件中的数据读取到内存中(Java程序 )
I 表示 intput ,是数据从硬盘进内存的过程,称之为读数据。
O 表示 output ,是数据从内存到硬盘的过程。称之为写数据。

1.2 IO的分类

根据数据的流向分为: 输入流 输出流
        1,输入流:把数据从硬盘上读取到内存中的流。
        2,输出流:把数据从内存 中写出到硬盘上的流。
 根据数据的类型分为: 字节流 字符流
       
        1,字节流:以字节为单位,操作所有类型的文件,包括音频视频图
              片等
        2,字符流:以字符为单位,只能操作纯文本文件。能用windows
              事本打开并能读的懂

1.3 IO的顶层父类

字节输入流 : 顶层父类 InputStream 抽象类
字节输出流 : 顶层父类 OutputStream 抽象类
字符输入流 : 顶层父类 Reader 抽象类
字符输出流 : 顶层父类 Writer 抽象类

四.字节流

一切文件数据 ( 文本、图片、视频等 ) 在存储时,都是以二进制数字的
形式保存,都一个一个的字节,那么传输时一样如此。所以,字节
流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无
论使用什么样的流对象,底层传输的始终为二进制数据。

2.1 字节输出流OutputStream

 方法:

public abstract void write(int b):一次写一个字节数据。
 
public void write(byte[] b):一次写一个字节数组数据。
 
public void write(byte[] b, int off, int len) :一次写一个字节数
组的部分数据

public void close():关闭此输出流并释放与此流相关联的任何系
统资源。

2.2 FileOutputStream

FileOutputStream 类的概述
java.io.FileOutputStream 类是OutputStream类的子类,用来表示是
文件输出流,用于将数据写出到文件。
FileOutputStream 类的构造方法
       
public FileOutputStream(File file):
创建文件输出流以写入由指定的 File对象表示的文件。

public FileOutputStream(String name): 
创建文件输出流以指定的名称写入文件。
注意 :当你创建一个流对象时,必须传入一个文件路径。该路径
下,如果没有这个文件,会创建该文件。如果有这个文件,会清空
这个文件的数据。

2.3 数据换行与追加

数据追加续写
public FileOutputStream(File file, boolean append):
 创建文件输出流以指定的名称写入文件。
如果第二个参数为true ,不会清空文件里面的内容。

public FileOutputStream(String name, Boolean append):
 创建文件输出流以指定的名称写入文件。
如果第二个参数为true ,不会清空文件里面的内容。
写出换行
windows : \r\n
linux : \n
mac : \r

2.4 字节输入流InputStream

java.io.InputStream 抽象类是表示字节输入流的所有类的超类,可
以读取字节信息到内存中。它定义了字节输入流的基本共性功能方
法。
public abstract int read(): 
每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回 -1。

public int read(byte[] b): 
每次读取b的长度个字节到数组中,返回读取到的有效字节个数,读取到末尾时,返回 -1。

public void close():
关闭此输入流并释放与此流相关联的任何系统资源。

2.5 FileInputStream

FileInputStream 类的概述
java.io.FileInputStream 类是 InputStream 类的子类 , 用来表示文件
输入流,从文件中读取字节。
FileInputStream 类的构造方法
FileInputStream(File file): 
通过打开与实际文件的连接来创建一个FileInputStream ,
该文件由文件系统中的文件对象 file命名。

FileInputStream(String name): 
通过打开与实际文件的连接来创建一个 FileInputStream ,
该文件由文件系统中的路径名 name命名。
注意: 当你创建一个流对象时,必须传入一个文件路径。该路径
下,如果没有该文件 , 会抛出 FileNotFoundException

2.6 读取字节

int read() ,每次可以读取一个字节的数据,提升为 int 类型,读取到
文件末尾,返回 -1

2.7 IO资源的处理

JDK7 版本前异常的捕获处理
public class demo01 {
    public static void main(String[] args) throws Exception {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
           fis = new FileInputStream("D:\\IO流(一).pdf");
           fos = new FileOutputStream("java_0725\\IO流(一).pdf");

            long begin = System.currentTimeMillis();

            int data;
            while ((data=fis.read())!=-1){
                fos.write(data);
            }

            long end = System.currentTimeMillis();

            System.out.println("所用时间为:"+(end-begin));
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(fis!=null){
                    fis.close();
                }
                if(fos!=null){
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
JDK7版本异常的捕获处理
JDK7 版本对流的释放做了优化 . 可以使用 try-with-resource 语句 ,
该语句确保了每个资源在语句结束时自动关闭。简单理解 : 使用此语
, 会自动释放资源 , 不需要自己在写 finally 代码块了
注意 : 使用前提 , 资源的类型必须是 AutoCloseable 接口的实现类
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class demo02 {
    public static void main(String[] args) throws Exception {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream("D:\\小米官网.html");
            fos = new FileOutputStream("java_0726\\小米官网.html");


        long begin = System.currentTimeMillis();

        byte[] buf = new byte[1024];

        int read;
        while ((read = fis.read(buf)) != -1) {
            fos.write(buf,0,read);
        }
        fis.close();
        fos.close();

        long end = System.currentTimeMillis();

        System.out.println("消耗时间:"+(end-begin));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}


    2.8 读字节数组

int read(byte[] b) 
每次读取b的长度个字节到数组中,返回读取到的有效字节个数,读取到末尾时,返回-1

    

helloworld~
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class demo03 {
    public static void main(String[] args) throws Exception {
        FileInputStream fis = new FileInputStream("java_0726\\hello.txt");

        byte[] buf = new byte[5];

        int len;
        while ((len=fis.read(buf))!=-1){//StringIndexOutOfBoundsException fis.read()
            System.out.println("输入数据为"+new String(buf,0,len));
        }
        fis.close();
    }
}

.字节缓冲流

增加代码高效率运行

字节缓冲流 BufferedInputStream BufferedOutputStream
字符缓冲流 BufferedReader BufferedWriter
缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大
小的缓冲区数组,通过缓冲区读写,减少系统 IO 次数,从而提高读
写的效率。
字节缓冲流的构造方法
public BufferedInputStream(InputStream in) :
创建一个 新的缓冲输入流。
public BufferedOutputStream(OutputStream out): 
创建一个新的缓冲输出流。
import java.io.*;

public class demo04 {
    public static void main(String[] args) throws Exception {
        String fis = "D:\\小米官网.html";
        String fos = "java_0726\\小米官网.html";

        BufferedInputStream bis =
                new BufferedInputStream(new FileInputStream(fis));

        BufferedOutputStream bos =
                new BufferedOutputStream(new FileOutputStream(fos));

        long begin = System.currentTimeMillis();

        byte[] buf = new byte[1024];
        int len;
        while ((len=bis.read(buf))!=-1){
            bos.write(buf,0,len);
        }
        long end = System.currentTimeMillis();
        System.out.println("共消耗:"+(end-begin));

        bis.close();
        bos.close();
    }
}

.Properties集合

4.1 Properties类的概述

java.util.Properties 继承于 Hashtable ,来表示一个持久的属性
集。它使用键值结构存储数据,每个键及其对应值都是一个字符
串。

4.2 Properties类的构造方法

public Properties() : 创建一个空的属性列表

4.3 Properties类存储方法

public Object setProperty(String key, String value):
 保存一对属性。

public String getProperty(String key) :
使用此属性列表中指定 的键搜索属性值。

public Set stringPropertyNames() :
获取所有键的名称的集合
public class DemoTest {
   public static void main(String[] args){
       // 创建属性集对象
       Properties properties = new Properties();
public void load(InputStream inStream):以字节流形式 , 把文
件中的键值对, 读取到集合中
       // 添加键值对元素
       properties.setProperty("张三", "北京");
       properties.setProperty("李四", "上海");
       properties.setProperty("王五", "深圳");
       properties.setProperty("赵六", "广州");
       // 打印属性集对象
       System.out.println(properties);
       // 通过键,获取属性值
       System.out.println(properties.getProperty("张 三"));
       System.out.println(properties.getProperty("李 四"));
       System.out.println(properties.getProperty("王 五"));
       System.out.println(properties.getProperty("赵 六"));
       // 遍历属性集,获取所有键的集合
       Set<String> strings =
properties.stringPropertyNames();
       // 打印键值对
       for (String key : strings ) {
           System.out.println(key+" --
"+properties.getProperty(key));
      }
  }
}

4.4 Properties类与流相关的方法

作用: 通过流对象,可以关联到配置文件上,这样就能够加载配置
文件中的数据了。
public void load(Reader reader):以字符流形式 , 把文件中的
键值对, 读取到集合中

public void store(OutputStream out, String comments):把集
合中的键值对,以字节流形式写入文件中 , 参数二为注释

public void store(Writer writer, String comments):把集合中
的键值对,以字符流形式写入文件中 , 参数二为注释
public class DemoTest {
   public static void main(String[] args) throws
IOException {
       //创建对象
       Properties prop=new Properties();
       //读取 db.properties属性配置文件
       FileInputStream fis=new
FileInputStream("java_0709\\db.properties");
       prop.load(fis);
       // 关闭流,释放资源
       fis.close();
       System.out.println(prop);
  }
}
注意事项:
文本中的数据,必须是键值对形式,可以使用空格、等号、冒号
等符号分隔。
如果配置文件中有中文,那么加载文件文件时,使用字符流 , 但是
开发中一般配置文件中不要写中文
public class DemoTest {
   public static void main(String[] args) throws
IOException {
       //创建对象
       Properties prop = new Properties();
       //存储元素
       prop.setProperty("name","zhangsan");
       prop.setProperty("age","18");
       //把集合中的数据,写入到配置文件
       FileOutputStream fos=new
FileOutputStream("java_0709\\info.properties");
       prop.store(fos,"lzw");
       // 关闭流
       fos.close();
  }
}

4.5 ResourceBundle工具类

java.util.ResourceBundle 它是一个抽象类我们可以使用它的子类
PropertyResourceBundle 来读取以 .properties 结尾的配置文件。
通过静态方法直接获取对象: static ResourceBundle
getBundle(String baseName) 可以根据名字直接获取默认语言环境
下的属性资源。参数注意 : baseName
属性集名称不含扩展名。
属性集文件是在 src 目录中的
ResourceBundle 中常用方法: String getString(String key) : 通过
键,获取对应的值
public class DemoTest {
   public static void main(String[] args) throws
IOException {
       //获取对象 (作用:读取项目工程的src目录下的.properties配置文件)
       ResourceBundle rb =ResourceBundle.getBundle("db");
       //只需要指定配置文件的名字即可
       //获取配置文件中的value值
       String username = rb.getString("username");
       String password = rb.getString("password");
       System.out.println(username);
       System.out.println(password);
  }
}

五.字符集

为什么字节流读取纯文本文件,会出现乱码 ?
如果使用字节流 , 把文本文件中的内容读取到内存时 , 可能会出现
乱码
如果使用字节流 , 把中文写入文本文件中 , 也有可能会出现乱码
读取hello.txt中 "你好" 两个汉字
public class DemoTest {
   public static void main(String[] args) throws
IOException {
       //字节输入流(读取中文数据)
       FileInputStream fis = new
FileInputStream("java_0709/hello.txt");
       //读取字节数据
       System.out.println((char)fis.read());
       System.out.println((char)fis.read());
       //释放流
       fis.close();
  }
}
因为字节流读中文,每次只能读一部分所以出现了乱码。
public class DemoTest {
   public static void main(String[] args) throws
IOException {
       //字节输入流(读取中文数据)
       FileInputStream fis = new
FileInputStream("java_0709/hello.txt");
       //读取字节数据
       byte[] buf=new byte[3];
       fis.read(buf);
       System.out.println(new String(buf));
       fis.read(buf);
       System.out.println(new String(buf));
       //释放流
       fis.close();
    }
}
字符集( Character set ,顾名思义是字符的集合。字符是各种文
字和符号的总称,包括文字、标点符号、图形符号、数字、控制符
号等。常用的字符集有: ASCII 字符集、 GBK 字符集、 Unicode 字符
集等。
标准 ASCII 字符集
ASCII(American Standard Code for Information Interchange)
美国信息交换标准代码,包括了英文、符号等。
标准 ASCII 使用 1 个字节存储一个字符,首尾是 0 ,总共可表示 128
字符
ASCII(American Standard Code for Information Interchange)
美国信息交换标准代码,包括了英文、符号等。
标准 ASCII 使用 1 个字节存储一个字符,首尾是 0 ,总共可表示 128
字符

.字符流

当使用字节流读取文本文件时,可能会有一个小问题。就是遇到中
文字符时,可能不会显示完整的字符,那是因为一个中文字符可能
占用多个字节存储。所以 Java 提供一些字符流类,以 字符 为单位读
写数据,专门用于处理文本文件。

2.1 字符输出流【Writer

字符输出流Writer类的概述

java.io.Writer 抽象类是表示用于写出字符流的所有类的超类,将指
定的字符信息写出到目的地。它定义了字节输出流的基本共性功能
方法。
字符输出流 Writer 类的常用方法

public void write(int c):写出一个字符。
public void write(char[] cbuf):将 b.length字符从指定的字符
数组写出此输出流。 
public abstract void write(char[] b, int off, int len):从指定的
字符数组写出 len字符,从偏移量 off开始输出到此输出流。 
public void write(String str) :写出一个字符串。
public void write(String str,int off,int len):写出一个字符串的
一部分。
public abstract void close():关闭流,释放资源,但是在关闭
之前会先刷新流。一旦关闭,就不能再写数据。
public abstract void flush():刷新流,还可以继续写数据。

2.2 FileWriter

FileWriter 类的概述
java.io.FileWriter 类是写出字符到文件的便利类。构造时使用系统默
认的字符编码 (UTF-8) 和默认字节缓冲区。
FileWriter 类的构造方法
FileWriter(File file):创建一个新的 FileWriter,给定要读取的File对
象。 
FileWriter(String fileName):创建一个新的 FileWriter,给定要读
取的文件的名称。 
FileWriter(File file,boolean append): 创建一个新的 FileWriter,
追加写入。 
FileWriter(String fileName,boolean append): 创建一个新的
FileWriter,追加写入。
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;

public class dm02 {
    public static void main(String[] args) throws Exception {
        FileWriter fw = new FileWriter("java_0727\\hello.txt");

        fw.write(97);
        fw.write('a');
        fw.write("\r\n");

        char[] cs = {'你','好','c','+','+'};
        fw.write(cs);
        fw.write("\r\n");

        fw.write(cs,0,4);
        fw.write("\r\n");

        fw.write("不知道写什么");
        fw.write("\r\n");

        fw.write("还是不知道写什么",0,8);

        fw.close();
    }
}

追加写入

import java.io.FileWriter;
import java.io.IOException;

public class dm03 {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("java_0727\\hello.txt",true);

        fw.write("111111"+"\n");

        fw.close();
    }
}
因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件
中。但是关闭的流对象,是无法继续写出数据的。如果我们既想写
出数据,又想继续使用流,就需要 flush 方法了。
flush:刷新缓冲区,流对象可以继续使用。
close:关闭流,释放系统资源。关闭前会刷新缓冲区。防止数
据丢失
即便是flush方法写出了数据,操作的最后还是要调用close方
法,释放系统资源。

2.3 字符输入流【Reader

字符输入流 Reader 类的概述
java.io.Reader 抽象类是表示用于读取字符流的所有类的超类,可以
读取字符信息到内存中。它定义了字符输入流的基本共性功能方
法。
字符输入流 Reader 类的常用方法
public int read():每次可以读取一个字符的数据,读取到文件末
尾,返回-1。 返回字符数据的编码值。
public int read(char[] cbuf):一次最多读取cbuf.length个字符数
据,并把读取的字符数据存储到cbuf数组中。返回实际读取到的字
符数据个数。 读取到文件末尾返回:-1

2.4 FileReader

FileReader 类的概述
java.io.FileReader 类是读取字符文件的便利类。构造时使用系统默
认的字符编码 (UTF-8) 和默认字节缓冲区。
FileReader 类的构造方法
FileReader(File file) 创建一个新的 FileReader ,给定要读取的
File 对象。
FileReader(String fileName) : 创建一个新的 FileReader ,给定要
读取的文件的名称。
public class DemoTest {
   public static void main(String[] args) throws
IOException {
       //创建流对象
       FileReader fr=new
FileReader("java_0709\\hello.txt");
       //操作 读数据
       int read = fr.read();
       /*
           System.out.println(read);
           System.out.println((char)read);
       */
       int len;
       while( (len=fr.read())!=-1 ){
           System.out.println((char)len);
      }
       //关闭流
      fr.close();
  }
}
public class DemoTest {
   public static void main(String[] args) throws
IOException {
       //创建流对象
       FileReader fr=new
FileReader("java_0709\\hello.txt");
       //操作 读数据
       char[] cbuf=new char[5];
//       int len=fr.read(cbuf);
//       System.out.println("第1次读取到的字符数据个
数:"+len);
//       System.out.println("第1次读取到的字符数
据:"+new String(cbuf,0,len));
//
//       len=fr.read(cbuf);
//       System.out.println("第2次读取到的字符数据个
数:"+len);
//       System.out.println("第2次读取到的字符数
据:"+new String(cbuf,0,len));
//
//       len=fr.read(cbuf);
//       System.out.println("第3次读取到的字符数据个
数:"+len);
//       System.out.println("第3次读取到的字符数
据:"+new String(cbuf,0,len));
//
//       len=fr.read(cbuf);
//       System.out.println("第4次读取到的字符数据个
数:"+len);
//       System.out.println("第4次读取到的字符数
据:"+new String(cbuf,0,len));
         int len;
         while((len=fr.read(cbuf))!=-1){
             String str = new String(cbuf,0,len);
             System.out.println(str);
        }
       //关闭流
      fr.close();
  }
}

ok了家人们。下周见

      

  • 29
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值