java学习-File类、IO流、字符流
File类
File类的介绍
1. File类 : 来自java.io包, 一个文件或者文件夹路径(目录)的抽象表现形式
2. 路径 : 表示文件或者文件夹存在位置的字符串, 举例 : D:\0720Java系统班\day01
1)绝对路径 : 带有根目录的路径, 使用时路径唯一, 没有二义性
例如 : windows 操作系统中的绝对路径就是带有盘符的路径
D:\0720Java系统班
2)相对路径: 相对某一个路径而言, 路径不唯一, 有二义性
Eclipse中 : 相对路径都是相对当前项目工程根目录而言
File类构造方法
1. File(String path) : 将path表示的文件或者文件夹路径封装成一个File类型对象
2. File(String parent, String child) : 将parent + child 拼接在一起,形成一个文件或者文件夹路径, 封装成一个File类型对象
3. File(File parent, String child): 将File类型父路径,与String类型的子路径拼接在一起, 形成一个文件或者文件夹路径, 封装成一个File类型对象
代码
public class Demo01_File构造 { public static void main(String[] args) { // 1. File(String path) : 将path表示的文件或者文件夹路径封装成一个File类型对象 String fu = "D:\\0720Java系统班\\day01"; // File f = new File("D:\\0720Java系统班\\day01"); File f = new File(fu); System.out.println(f);// D:\0720Java系统班\day01 // 2.File(String parent, String child): 将parent + child 拼接在一起,形成一个文件或者文件夹路径, 封装成一个File类型对象 File f1 = new File("D:\\0720Java系统班\\day01", "笔记"); System.out.println(f1);// D:\0720Java系统班\day01\笔记 // 3. File(File parent, String child): 将File类型父路径, // 与String类型的子路径拼接在一起, 形成一个文件或者文件夹路径, 封装成一个File类型对象 File f2 = new File(f, "视频"); System.out.println(f2);// D:\0720Java系统班\day01\视频 }
File类创建文件和文件夹
1.mkdir() : 表示将file类型所表达的文件夹路径创建出来, 返回值类型boolean类型
注意 : 只能创建file最后一级文件夹, 如果最后一级的文件夹的父路径不存在, 无法创建成功, 每次只能创建出一级文件夹路径
2.mkdirs() : 表示将file所表达文件夹路径创建出来, 将file中所有不存在的父路径一同创建出来, 可以创建出多级文件路径, 返回值类型boolean
public class Demo02_File类创建 { public static void main(String[] args) throws IOException { File f = new File("D:\\123.txt"); // 1. 创建文件 boolean boo = f.createNewFile(); System.out.println(boo); // 2. 创建文件夹 File f1 = new File("D:\\a"); System.out.println(f1.mkdir());// true File f2 = new File("D:\\b\\c"); System.out.println(f2.mkdir());// false // 创建多级文件夹 System.out.println(f2.mkdirs());// true }
File类删除和重命名功能
1.delete() : 删除file所表示的文件或者文件夹,删除成功返回true, 删除失败返回false
注意 : 如果删除的是文件夹, 那么要求这个文件夹必须是空文件夹, 否则无法删除; 尽量保证删除安全性, 因为delete方法不走回收站,直接删除文件或者文件夹
2.renameTo(File f) : 将方法调用的file对象所表示的文件进行重命名, 命名以参数f名字为准, 返回值类型boolean类型
1) 如果方法调用file路径与参数f的路径一致, 只是文件名不一致, 表示修改文件名
2) 如果方法调用file路径与参数f的路径不一致, 那么表示先将源文件剪切到f路径下, 再进行重命名
代码
public class Demo03_File删除和重命名 { public static void main(String[] args) { /* File f = new File("D:\\123.txt"); // 1. 删除文件 System.out.println(f.delete());// true // 2. 删除文件夹(空) File f1 = new File("D:\\a"); System.out.println(f1.delete()); // 3. 删除文件夹(非空) File f2 = new File("D:\\b"); System.out.println(f2.delete());*/ // 4. 重命名(同路径下) /* File f3 = new File("D:\\b\\new.txt"); boolean boo = f3.renameTo(new File("D:\\b\\old.txt")); System.out.println(boo);*/ // 5. 重命名(不同路径) : 先剪切,再重命名 File f4 = new File("D:\\b\\c\\old2.txt"); File f5 = new File("D:\\b\\old.txt"); System.out.println(f5.renameTo(f4)); } }
File类判断功能
1.exists()测试此抽象路径名表示的文件或者目录是否存在
2.isDirectory()测试此抽象路径名表示的文件是否是一个目录
3.isFile()测试此抽象路径名表示的文件是否是一个文件
代码
public class Demo04_File判断功能 { public static void main(String[] args) { File f = new File("D:\\b\\c\\old2.txt"); System.out.println(f.exists());// true System.out.println(f.isFile());// true File f1 = new File("D:\\b\\c"); System.out.println(f1.exists());// true System.out.println(f1.isDirectory());// true System.out.println(f1.isFile());// false System.out.println("-----------"); File f2 = new File("D:\\b\\c\\d"); System.out.println(f2.exists());// false } }
File类获取功能
- getAbsolutePath(): 获取到File所表示的文件或者文件夹的绝对路径, 返回一个String类型字符串
- getPath() : 获取到File所表示的文件或者文件夹的路径, file对象中封装的路径是什么, 结果就是什么,返回一个String类型字符串
- getName() : 获取到File表示的文件或者文件夹路径最后一部分的名字, 或者是文件名或者是最后一个级别的文件夹名,返回一个String类型字符串
- length() : 表示获取到File类型所表示文件的大小, 以字节为计算粒度(length()方法无法计量文件夹大小), 通常使用在一个文件进行操作之前, 先验证文件是否存在, 文件大小是否不为0, 返回值类型long类型
- list() : 将当前file所表示的文件夹路径下的所有文件和文件夹以字符串的形式获取到,存储在String[]
- listFiles() : 将当前file所表示的文件夹路径下的所有文件和文件夹以File类型的形式获取到,存储在File[]
代码
public class Demo05_File类获取功能 { public static void main(String[] args) { // 1. 提供文件就是绝对路径 File f = new File("D:\\b"); // 1)getAbsolutePath(): 获取到File所表示的文件或者文件夹的绝对路径, 返回一个String类型字符串 String path1 = f.getAbsolutePath(); System.out.println(path1);// D:\b // 2).getPath() : 获取到File所表示的文件或者文件夹的路径, file对象汇总封装的路径是什么, 结果就是什么,返回一个String类型字符串 System.out.println(f.getPath() + "---"); // 3)getName() : 获取到File表示的文件或者文件夹路径左后一部分的名字, 或者是文件名或者是最后一个级别的文件夹名,返回一个String类型字符串 System.out.println(f.getName()+"+++"); // 2. 提供文件是相对路径 File f1 = new File("a\\123.txt"); System.out.println(f1.getAbsolutePath());// D:\eclipse-workspace\day16\a\123.txt System.out.println(f1.getPath()+"----"); // a\123.txt System.out.println(f1.getName()+ "+++");// 123.txt System.out.println(f1.exists());// false // 3. length File f2 = new File("first.txt"); // 4)length() : 表示获取到File类型所表示文件的大小, 以字节为计算粒度(length()方法无法计量文件夹大小) System.out.println(f2.length());// 4 // 4. list--->String[] File f3 = new File("D:\\b"); // 5) 将当前file所表示的文件夹路径下的所有文件和文件夹以字符串的形式获取到,存储在String[] String[] ss = f3.list(); System.out.println(Arrays.toString(ss)); // 5. listFiles--->File[] // 将当前file所表示的文件夹路径下的所有文件和文件夹以File类型的形式获取到,存储在File[] File[] ff = f3.listFiles(); System.out.println(Arrays.toString(ff)); } }
IO流
IO流介绍
- IO : 解释说明
I : 大写字母I, 表示input, 输入, 其他设备数据同步到内存中
O : 大写字母O, 表示output, 输出, 内存中的数据同步到其他设备中
2.IO流向:
IO流的分类
- IO流功能分类:
1) 字节流 : 以字节为粒度操作文件
a : 字节输入流 InputStream
b : 字节输出流 OutputStream
2) 字符流 : 以字符为粒度进行文件的操作
a : 字符输入流 Reader
b : 字符输出流 Writer
2.IO流根据流向分类:
1) 输入流 : 数据从其他设备到内存
2) 输出流 : 数据从内存到其他设备
IO流书写流程
- 使用流资源之前,先导包
- 使用流资源的时候, 需要处理异常(声明, 处理)
- 使用流资源结束后, 必须关闭流资源 close();
字节流
字节流介绍
- 字节流 : 通过字节进行信息操作
- 字节流 :
1) 字节输入流 : InputStream, 来自于java.io包
2) 字节输出流 : OutputStream, 来自于java.io包
字节输入流FileInputStream
1. 字节输入流 : 父类InputStream, 来自于java.io包, InputStream是抽象类, 需要一个子类FileInputStream :
FileInputStream主要实现与磁盘文件进行交互, 从磁盘文件中读取数据到代码中, 以字节进行文件内容读取, 可以单个字节进行读取, 也可以通过字节数组进行读取, 因为所有文件都是由字节组成的,因此FileInputStream 可以读取各种各样的文件内容, 文本, 图片, 视频, 压缩包...
2.FileInputStream构造方法:
1) FileInputStream(String path) : 将path所表示的文件路径, 封装在字节输入流中, 可以通过字节输入流从文件中读取内容
2) FileInputStream(File f): 将f所表示的文件路径, 封装在字节输入流中, 可以通过字节输入流从文件中读取内容
注意 : 封装在输入流中的路径, 必须是文件级别, 流资源无法操作文件夹
3.使用read方法读取文件内容:
1) read() : 每次从文件中读取出一个字节, 将读取到的字节转换成一个int类型整数作为读取结果, 如果读取-1,证明文件读取完毕
2) read(byte[] arr) :每次最多从文件中读取出arr.length个字节, 将读取到的字节放置到参数arr数组中, 通过查看数组中的内容相当于读取文件内容
1) 返回值类型 : int , 表示每次读取到的字节个数
2) 如果读取-1,证明文件读取完毕
代码
public class Demo01_FileInputStream { public static void main(String[] args) throws IOException { // FileInputStream fis1 = new FileInputStream(new File("first.txt")); // 1. 绑定一个数据源 : 从first.txt文件中读取数据 FileInputStream fis = read1(); //read2(fis); // 使用字节数组读取文件内容 // read3(fis); // read4(fis); // 必须关闭资源 fis.close(); } // 4. 使用字节数组读取文件优化 public static void read4(FileInputStream fis) throws IOException { byte[] arr = new byte[4]; // 定义len表示每次读取到的字节个数 int len; while((len = fis.read(arr)) != -1) { System.out.print(new String(arr,0,len)); } } // 3. 使用字节数组读取文件 public static void read3(FileInputStream fis) throws IOException { byte[] arr = new byte[4]; int count1 = fis.read(arr); // System.out.println(count1);// 4 System.out.println(new String(arr,0,count1));// abcd int count2 = fis.read(arr); // System.out.println(count2);// 2 System.out.println(new String(arr,0,count2));// -1cd int count3 = fis.read(arr); // System.out.println(count3);// -1 System.out.println(new String(arr,0,count3));// -1cd } // 2. 单个字节读取文件优化 public static void read2(FileInputStream fis) throws IOException { // 表示每次读取到的字节结果 int len; while((len = fis.read()) != -1) { // 读 System.out.println((char)len); } } // 1. 单个字节读取文件 public static FileInputStream read1() throws FileNotFoundException, IOException { FileInputStream fis = new FileInputStream("first.txt"); int first = fis.read(); System.out.println(first);// 97 int second = fis.read(); System.out.println(second);// 98 int three = fis.read(); System.out.println(three);// 99 int four = fis.read(); System.out.println(four);// 100 int end = fis.read(); System.out.println(end);// -1 return fis; } }
字节输出流FileOutputStream
1.字节输出流 : 父类OutputStream, 来自于java.io包, OutputStream是抽象类, 需要一个子类FileOutputStream :
FileOutputStream 主要实现与磁盘文件进行交互, 可以单个字节或是是通过字节数组向文件中写入内容, 因为所有文件都是由字节组成的, 因此可以操作很多类型文件
2.FileOutputStream 构造方法:
1) FileOutputStream(String path) : 将path所表示的文件路径, 封装在字节输出流中, 可以通过字节输出流向文件中写入内容
2) FileOutputStream(File path) : 将path所表示的文件路径, 封装在字节输出流中, 可以通过字节输出流向文件中写入内容
3.使用write方法向文件中写入内容: write方法没有返回值类型
1) write(int b) : 将一个字节b写入到文件中
2) write(byte[] arr) : 将字节数组arr中的内容写入到文件中
3) write(byte[] arr, int beginIndex, int length) : 将字节数组从beginIndex索引位置开始, 截取length个字节写入到文件中, 写入字节数组的一部分到文件
代码
public class Demo02_FileOutputStream { public static void main(String[] args) throws IOException{ // 1. 创建出一个字节输出流: 绑定一个数据目的 // 如果要写入的文件路径存在, 为文件不存在, 那么自动创建出文件 FileOutputStream fos = new FileOutputStream("my.txt"); // 2. 向文件中写入内容,单个字节 fos.write(99);// c // 3. 向文件中写入字节数组 byte[] b = {65,66,67,68}; fos.write(b); // 4.向文件中写入字节数组一部分 fos.write(b, 1, 2);// 66, 67 B C // 5. 将字符串转换成字节数组, 将字节数组写入文件中 fos.write("今天星期一".getBytes()); // 必须关闭资源 fos.close(); } }
字节高效缓冲流
- 高效缓冲流 :
BufferedInputStream : 字节高效缓冲输入流, 高效读取
BufferedOutputStream : 字节高效缓冲输出流, 高效写入
2.高效缓冲流都是包装类, 主要功能就是将普通字节输入或者输出流, 包装成一个高效缓冲流, 构造方法体现了缓冲流的包装性:
BufferedInputStream(InputStream in)
BufferedOutputStream(OutputStream out)
3.高效缓冲流高效原理:
1) BufferedInputStream : 当创建出一个BufferedInputStream流资源对象时, 系统底层会开辟一个大小为8192的字节数组, 当使用read方法从文件中读取内容时, 一次性的最多从文件中读取出8192个字节, 将字节存放在底层8192数组中, 接下来再使用read方法读取,就是从底层数组中读取内容, 从数组读取数据效率非常高; 如果8192字节数据读取为完毕, 下一次的read方法再继续最多从文件中读取8192,直到文件读取完毕为止
2) BufferedOutputStream : 当创建出一个BufferedOutputStream 流资源对象时,系统底层会开辟一个大小为8192的字节数组, 每次向文件中写入数据, 先写入到底层8192数组缓冲中, 当数组8192写满, 自动将数组中的数据同步到文件中, 如果没有将8192写满, 当close关闭资源之前, 将所有的缓冲区中数据同步到文件中,减少了与磁盘的交互, 极大的增加了流资源性能
案例 : 使用高效缓冲流复制一个视频,测试其消耗的时间
代码
public class Demo04_BufferedStream { public static void main(String[] args) throws IOException{ long begin = System.currentTimeMillis(); // 1. 使用高效字节缓冲流 : 绑定一个数据源 BufferedInputStream bis = new BufferedInputStream( new FileInputStream("D:\\0720Java系统班\\day01\\视频\\02.Java语言跨平台性.mp4")); // 2. 使用高效字节缓冲流 : 绑定一个数据目的 BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream("D:\\copyTV.mp4")); int len; while((len = bis.read()) != -1) { bos.write(len); } long end = System.currentTimeMillis(); System.out.println(end-begin); bos.close(); bis.close(); } }