java自学之路-day15
JAVA15
IO
IO概述
l i/o全称:
input/output
l 之前的程序都是在内存中,一旦结束就没有了
l 如果需要永久使用这些数据就需要持久化存储
l 需要用到IO技术 将数据放到持久化设备
l Output 写 Input 读 IO操作两种方方式
File类
概述
l 数据存在文件中 文件在文件夹中 路径
l 操作这些文件夹就需要用到File类
作用 特点
l Java.io 包中
l 文件和目录路径名的抽象表现形式
l / Linux盘符 \ Windows盘符
l 将操作系统中的文件目录路径封装成File对象
l 提供方法操作系统中的内容
l File与系统无关的类
l 文件 File 目录 Directory 路径 Path
静态成员变量
pathSeparator
l String 类型
l 实际是char类型的变形 加了个 +“”
l 与系统有关的路径分隔符
l 打印结果为 ;
l ;表示目录的分隔
l Linux目录分隔符是 :
separator
l 与系统有关的默认名称分隔符
l 打印结果为 \
l Linux是 /
l 不要写死分隔符
l 与系统无关的程序 需要使用这个常量
构造方法
三种重载形式
File(String pathname)
l 传递路径名
l 可以写到文件夹 也可以写到文件
l 示例
l 打印结果为 路径
l Windows系统文件名可以不区分大小写
l 即使路径错了也不报错 因为File只是把路径变为File对象来调用方法 不分辨是否正确
l 有专门的方法exits()
相对路径和绝对路径
l 绝对路径
- 在系统中具有唯一性
l 相对路径
- 路径之间的相对关系
- 父目录唯一性
- 子目录可以多个
File(String parent,String child)
l 传递路径
l 传递字符串父路径 字符串子路径
l 示例
l 单独控制父路径和子路径
l 比如用户输入子路径和父路径
File(String parent,String child)
l 传递路径
l 传递File类型的父路径 字符串子路径
l 父路径可以直接使用File的功能
l
File(URI uri)
File类的创建和删除文件功能
创建文件功能
l Boolean CreateNewFile()
l 创建成功返回true 否则返回 false
l 需要进行异常处理 异常类在io包里
l 示例
运行结果
l 文件名是汉字
创建文件夹
l Boolean mkdir()
l 创建成功返回true 否则返回 false
l 可以创建一层或多级目录 Boolean mkdirs()
l 示例
File类的删除功能
l Boolean delete()
l 删除成功返回true 否则返回false
l 删除不走回收站 直接从硬盘中删除
File类的获取功能
l String getName()
- 返回路径中表示的文件或文件夹名
- 示例
l String getPath()
- 将封装的抽象路径变为一个字符串
- 相当于toString
- 示例
l Long length()
- 返回路径中表示的文件的字节数
- 无法获取到文件夹的字节数
- 示例
l getAbsolutePath() getAbsoluteFile()
- getAbsolutePath()返回String
- getAbsoluteFile() 返回File对象
- 获取绝对路径
- 如果写的是相对路径 获取的是工程的根目录
- 示例
l getParent()getParentFile()
- getParent()返回String对象
getParentFile()返回File对象
- 获取父路径
- 示例
File类的判断功能
l boolean exists()
- 判断构造方法中的封装路径是否存在
- 存在返回true 不存在返回false
- 示例
l isDirectory()
- 返回布尔值
- 是文件夹返回true 不是文件夹返回false
- IsFile() 判断是不是文件
- 示例
File另一种获取功能
l List
- String[] list()
- 获取到File构造方法中封装的路径中的文件和文件夹名(遍历一个目录)
- 返回的是目录和文件的名字
- 示例
l listFile()
- File[ ] listFiles()
- 获取到File构造方法中封装的路径中的文件和文件夹名(遍历一个目录)
- 返回的是目录和文件的全路径名 的一个File数组
- 示例
l listRoots()
- 获取到系统的所有根目录
- 返回一个File数组
文件过滤器
l 遍历方法ListFiles()重载形式
l ListFiles(FileFilter filter)接口类型
l 传递FileFilter的接口实现类
l 查看文档没有实现类 自定义实现类
l 示例
原理
- listFile()在遍历目录的同时,获取到了文件的全路径
- 同时调用过滤器的方法accept将获取到的全路径传递给accept方法的参数pathname
- accept方法接受到了参数pathname,参数是listFiles传递来的
- 然后进进行判断
- 如果路径是java文件 就返回true 否则 返回false
- 一旦方法返回true 就将路径放到数组中
- 一旦方法返回false 就不会将路径放到数组中
递归遍历全目录
l 首先遍历demo目录
l 然后遍历demo下的a目录
l 文件不能遍历只能遍历文件夹
l 所以判断路径是不是文件夹 isDirectory
l 如果是就遍历这个目录 递归调用本方法
l 如果不是目录就直接打印这个目录
l 为了打印出原本的父目录 因此需要先打印下路径
l
递归
l 概念
- 方法自己调用自己
- 适合于方法中运算的主体不变,但运行的时候参与运行的方法参数会变化
- 直接递归 a调用a方法
- 间接递归 a调用b 调用 c c调用a
l 注意
- 递归一定要有出口 必须能让程序停下来
- 递归次数不能过多
- 构造方法不能递归
l 练习
- 求和计算
速度慢 执行100次
a) 多次调用方法 进栈
b) 遇到Return方法结束
a) 求阶乘
a) Int只能到13-14
- 递归计算裴波纳多数列
public static double sum(double n){
if(n==1||n==2){
return 1;
}else{
return sum(n-1)+sum(n-2);
}
}
IO流对象
输入和输出
l 文件到程序 输入
l 程序到文件 输出
字节流
OutputStream 字节输出流
概述
l 一次操作1个字节 8个二进制位bit
l 写入文件 任意文件
l 抽象类
l Java.io包
l 表示输出字节流的所有类的超类
l 方法是写入文件的方法
方法
l write(int b)写入一个字节
l write(byte[] b)写入字节数组
l write(byte[] b,int off,int len)写入字节数组 off开始写入索引 len写入个数
l close()方法 关闭流对象 释放与此流相关的资源 否则无法删除
l 使用需要子类
子类
l FileOutputStream
- 写入数据文件
- 构造方法重载5个
- 构造方法作用是绑定一个输出目的
- 参数 File封装文件 String字符串的文件名
- 使用步骤
a) 创建流子类的对象,绑定输出数据的目的
b) 调用流对象方法write写入文件 进行输出
c) close释放资源
- 可以根据路径创建文件,如果文件存在,直接覆盖
- 示例
n 写入一个字节
a) 文本工具打开会先过编码表
b) 所以写入的100是在编码表中对应的d
c) 写入的49 48 48对应的是100
n 写入一个字节数组
如果是负数
则是汉字 负数代表汉字 两个负数代表一个汉字 一个汉字两个字节 一个数字一个字节
少写一个负数 会缺少
n 写入一部分字节数组
只写入了BC
n 写入字节数组的简便方式
n 文件的续写和换行符号
- 续写
a) 在FileOutputStream的构造方法中的第二个参数加入true
b) 示例
- 换行
a) \t \r
b) 符号换行
c) 写在上一行的末尾 或者下一行的开头
d)
InputStream字节输入流
概述
l 所有字节输入流的超类
l 读取任意文件 每次只读取一个字节
l 抽象类
方法
l 读取方法 read()
- 返回值int
- 读取一个字节
l 读取方法read(byte[] b)
- 返回值是int
- 读取一定量的字节 存储到数组中
子类
l FileInputStream
n 构造方法 为这个流对象绑定数据源
n 读取步骤
- 创建字节输入流的的子类对象
- 调用read方法读取
- 关闭资源
n 示例
- 只要执行一次read就会自动读取下一个字节。返回值是返回读取到的字节,
- 读取到数据的结尾是会返回-1
- 如果文件中有-1也不影响 因为这是两个字节
- 如果文件太大,就要定义len(read方法返回值)循环读取
- 不能直接写fish.read()代替len 因为每执行一次read就会自动读取下一个字节
n read(byte[] b)读取
- 返回的int代表数组长度
- 示例 把数组变为字符串 方法 new String(byte[] b)
没有读取完毕 继续读取
读取到数据末尾都是-1
n 原理分析图
- 程序由JVM虚拟机运行 虚拟机没有这个功能 调用系统的功能
- 首先装一个字节 a 因为有两个位置 所以又装了一个字节 b
- 指针指向谁把谁装到数组中
- 之后 又装了c d 覆盖了原来的a b
- 之后又装了个e 覆盖了 c 所以是输出e d
- 之后又继续装 没有元素但是有结束标记
- 读取到结束标记 返回给JVM 之后JVM返回-1给read方法
数组作用 缓冲文件字节 提高效率
Int返回值 表示读取到的有效字节个数
因此改为循环读取
结果多一个 d 因此将数组长度需要变为5
具有可变性 需要进一步进行改进
由于文件大小不定 因此数组应该设置为1024的整数倍
IO中的异常处理
l 不选择抛出异常
l 使用try catch
l close发法写到finally 仍然需要异常处理
l 如果出现异常无法进行处理 只能抛出运行时异常
l 示例
如果建立文件失败 不需要关资源 因此在close方法前需要对流对象进行判断是否为null
文件复制
原理分析
l InputStream读取 OutputStream写入
l 复制可扩展为上传下载
l
l 步骤(一次读一个字节)
- 定义连个流的对象变量
- 字节输入流绑定数据源 读取源文件内容输入程序
- 字节输出流绑定数据目的 从程序中输出源文件内容到另一个文件
- 输入 读取一个字节
- 输出 写一个字节
l 示例
- 需要异常处理
- 说明
- 绑定
- 复制
- 处理异常
l 步骤(读取字节数组)
- 数组缓冲 提高效率
- FileInputStream 读取字节数组
- FileOutputStream 写字节数组
- 定义两个流的变量
- 复制
- 处理异常
测量时间
字符编码表
l 以上都是对数字字母的处理
l 字符流目的是为了处理文本文件
l 所以需要了解编码表
l Ascii码表 一个字节中的7位就可以表示 对应的字节都是整数
l iso-8859-1 拉丁码表 用一个字节的8位
l GB2312 简体中文码表 包含6000-7000中文和汉字,两个字节表示 两个字节第一个字节是1,第二个字节可能是0
- GBK 目前最常用的中文码表 2万的中文和符号 两个字节表示 两个字节第一个字节开头是1,第二个字节开头可能是0
- GB18030 最新的中文码表 还没正式使用
l Unicode 国际标准码表 无论是什么文字 都用两个字节
- Java中的char类型就是用的这个码表 char c=’a’ 占用两个字节
- Java中的字符串是按照系统默认码表解析的,简体中文版 字符串默认的码表是GBK
l UTF-8 基础unicode 一个字节就可以存储数据 就不要用两个字节存储 后期开发经常使用 而且这个码表更加标准化 在每一个字节头加入了编码信息(后期到api中查找)
l 能识别的中文码表:GBK UTF-8 正因为识别码表不唯一 表现的负数不同 所以涉及到了解码问题
l 开发而言 常见的编码 GBK UTF-8 ISO-8859-1
l 编码 文字变数字97 98 99
l 解码 数字变文字 a b c
Writer 字符输出流
概述
l Java.io.Writer
l 所有字符输出流的超类
l 只能写文本文件
方法 write
l write(int c)写一个字符
l write(char[] c)写字符数组
l write(char[],int,int )写字符数组的一部分 开始索引 写几个
l write(String s)写入字符串
子类
l FileWriter
l 构造方法 写入的数据目的
l 构造方法 接收的参数类型 File 类型对象或者 String 文件名
l 字符输出流写数据 必须使用flush 刷新方法 否则就不会写入
l 示例
- 写一个字符
- 写一个字符数组
如果不写flush只在最后写个close也能写进去,但是最好写一个字符数组刷新一下 因为如果关闭时一起刷新会放在内存中,从而消耗系统资源 这样会节省系统资源
- close也有刷新的功能
- 写一个字符数组的一部分
- 写入字符串
- 和字节流写数据都一样 只不过write方法中的参数 变为了char类型
字符输入流读取文本文件 Reader类
概述
l 只能读取记事本能打开读懂的文件 文本文件
l java.io.reader
l 所有字符输入流的超类
方法
l read() 读取一个字符
l read(char [] c)读取字符数组
l 和字节流就是byte和char的区别
l 没有读取字符串的功能
因为字符串的概念无法确定 单个也就字符串 多个也就字符串
子类
l FileReader
l 构造方法
绑定数据源
l 参数 File类型变量和String文件名
l 示例
- 读取一个字符
可以读取文本文件
- 读取一个字符数组
flush和close的区别
l flush刷新完 流还可以用
l close刷新完 流就关闭了
l flush 只有写文本需要用 其他不需要用
字符流复制文本文件
示例
l 默认码表 GBK
l