目录
字节流写数据【FileOutputStream】【write】
字节流读数据【FileInputStream】【read】
字节缓冲流【BufferedOutputStream】
IO流是什么?
1,可以将数据从本地文件中读取出来
2,可以将数据从内存保存到本地文件
File类是什么?
1,在读写数据时告诉虚拟机要操作的(文件/文件夹)在哪
2,对(文件/文件夹)本身进行操作。包括创建,删除等。
File类
File类概述和构造方法
-
File类介绍
-
它是文件和目录(文件夹)的抽象表示【表示是一个路径】
-
文件和目录是可以通过File封装成对象的
-
对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已.它可以是存在的,也可以是不存在的.将来是要通过具体的操作把这个路径的内容转换为具体存在的
-
-
File类的构造方法
方法名 说明 File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例 File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例 File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例 private static void method3() { //File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的File实例 File file1 = new File("C:\\itheima"); String path = "a.txt"; File file = new File(file1,path); System.out.println(file);//C:\itheima\a.txt } private static void method2() { //File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的File实例 String path1 = "C:\\itheima"; String path2 = "a.txt"; File file = new File(path1,path2);//把两个路径拼接. System.out.println(file);//C:\itheima\a.txt } private static void method1() { //File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的File实例 String path = "C:\\itheima\\a.txt"; File file = new File(path); //问题:为什么要把字符串表示形式的路径变成File对象? //就是为了使用File类里面的方法. }
绝对路径和相对路径
-
绝对路径
是一个完整的路径,从盘符开始
-
相对路径
是一个简化的路径,相对当前项目下的路径
public class FileDemo02 {
public static void main(String[] args) {
// 是一个完整的路径,从盘符开始
File file1 = new File("D:\\itheima\\a.txt");// 是一个简化的路径,从当前项目根目录开始
File file2 = new File("a.txt");
File file3 = new File("模块名\\a.txt");
}
}
File类创建功能
-
方法分类
方法名 说明 public boolean createNewFile() 当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件
不管有没有后缀名,只能创建文件,即使写aaa没有后缀也不能创建文件夹
注意:所创建文件的文件夹必须存在
public boolean mkdir() 创建由此抽象路径名命名的目录【创建单级文件夹】【多级文件夹:嵌套一个又一个文件夹】 public boolean mkdirs() 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录【创建一个多级文件夹】
public class FileDemo3 {
public static void main(String[] args) throws IOException {
//public boolean createNewFile() 创建一个新的空的文件
//注意点:
//1.如果文件存在,那么创建失败,返回false
//2.如果文件不存在,那么创建成功,返回true
//3.createNewFile方法不管调用者有没有后缀名,只能创建文件.
File file1 = new File("C:\\itheima\\a.txt"); 【如果itheima文件夹不存在,创建失败】
File file1 = new File("C:\\itheima\\aaa");// aaa理论上应该是一个文件夹,但创建出来的依旧是文件,只是此文件没有后缀名
boolean result1 = file1.createNewFile();
System.out.println(result1);
//public boolean mkdir() 创建一个单级文件夹
//注意点:
//1.只能创建单级文件夹,不能创建多级文件夹
//2.不管调用者有没有后缀名,只能创建单级文件夹
//File file = new File("C:\\itheima\\aaa\\\bbb\\\ccc");//执行的话返回一个false,因为mkdir只能创建单级文件夹
File file = new File("C:\\itheima\\aaa.txt");//即使加了后缀名,创建的依旧是文件夹,只是文件夹名字叫【aaa.txt】
boolean result = file.mkdir();
System.out.println(result);
//public boolean mkdirs() 创建一个多级文件夹
//注意点:
//1,可以创建单级文件夹,也可以创建多级文件夹
//2.不管调用者有没有后缀名,只能创建文件夹
File file = new File("C:\\itheima\\aaa\\\bbb\\\ccc");// 创建成功,多级文件夹
File file = new File("C:\\itheima\\aaa"); //创建单极的文件夹也可以
File file = new File("C:\\itheima\\aaa.txt"); //创建成功,单级文件夹名叫aaa.txt
boolean result = file.mkdirs();
System.out.println(result);
//疑问:
//既然mkdirs能创建单级,也能创建多级.那么mkdir还有什么用啊? 是的,所以mkdir了解一下即可
}
File类删除功能
-
方法分类
方法名 说明 public boolean delete() 删除由此抽象路径名表示的文件或目录
public class FileDemo4 {
//注意点:
//1.不走回收站的.【直接从根源删除,不会停留在回收站】
//2.如果删除的是文件,那么直接删除.如果删除的是文件夹,那么能删除空文件夹【不经过回收站】
//3.如果要删除一个有内容的文件夹,只能先进入到这个文件夹,把里面的内容全部删除完毕,才能再次删除这个文件夹
//简单来说:
//只能删除文件和空文件夹.
public static void main(String[] args) {
File file = new File("C:\\itheima\\a.txt");【删除一个文件】
boolean result = file.delete();
System.out.println(result);
File file = new File("C:\\itheima");
boolean result = file.delete();
System.out.println(result);
}
File类判断和获取功能
-
判断功能
方法名 说明 public boolean isDirectory() 测试此抽象路径名表示的File是否为目录 public boolean isFile() 测试此抽象路径名表示的File是否为文件 public boolean exists() 测试此抽象路径名表示的File【路径】是否存在 -
获取功能
方法名 说明 public String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串 public String getPath() 将此抽象路径名转换为路径名字符串 public String getName() 返回由此抽象路径名表示的文件或目录的名称 public File[] listFiles() 返回此抽象路径名表示的目录中的文件和目录的File对象数组
getName方法注意点:
1.如果调用者是文件,那么获取的是文件名和后缀名
2.如果调用者是一个文件夹,那么获取的是文件夹的名字
listFiles()方法
进入文件夹,获取这个文件夹里面所有的文件和文件夹的File对象,并把这些File对象都放在一个数组中返回.
//包括隐藏文件和隐藏文件夹都可以获取.
注意事项:
1.当调用者不存在时,返回null
2.当调用者是一个文件时,返回null
3..当调用者是一个空文件夹时,返回一个长度为0的数组
4.当调用者是一个有内容的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回
5.当调用者是一个有隐藏文件的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏内容
6.当调用者是一个需要权限才能进入的文件夹时,返回null
IO流
O:输入/输出(Input/Output)【读写的过程】
input:从你硬盘到内存,简称 读数据 读,in,进去
output:从内存到硬盘,简称 写数据 写,out,出去
用内存为主体,对内存进行输入,从内存输出
按照数据的流向:
输入流:从硬盘往内存,读【input】 【从硬盘读到内存】
输出流:从内存到硬盘,写【output】 【从内存写道硬盘】
按照数据分类:
-
字节流【操作所有类型的文件 eg:视频音频图片等】
-
字节输入流【从硬盘输入到内存,进行input,把数据从硬盘读入到内存read】
-
字节输出流【从内存输出到硬盘,进行output,把数据从内存写入到硬盘write】
-
-
字符流【只能操作纯文本文件 eg:java文件,txt文件等】
-
字符输入流
-
字符输出流
-
一般来说,我们说IO流的分类是按照数据类型来分的
什么是纯文本文件?
用windows记事本打开能读的懂,那么这样的文件就是纯文本文件。
如果不确定文件类型,优先使用字节流。字节流是万能的流 。
字节流
字节流抽象基类
-
InputStream:这个抽象类是表示字节输入流的所有类的超类
-
OutputStream:这个抽象类是表示字节输出流的所有类的超类
-
子类名特点:子类名称都是以其父类名作为子类名的后缀
字节流写数据
-
字节输出流
-
FileOutputStream(String name):创建文件输出流以指定的名称写入文件
-
-
使用字节输出流写数据的步骤
-
创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)
-
调用字节输出流对象的写数据方法
-
释放资源(关闭此文件输出流并释放与此流相关联的任何系统资源)
-
构造方法:
FileOutputStream(String name)创建一个向具有指定名称的文件中写入数据的输出文件流。 FileOutputStream(File file) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。参数:写入数据的目的 String name:目的地是一个文件的路径 File file:目的地是一个文件 构造方法的作用: 1.创建一个FileOutputStream对象 2.会根据构造方法中传递的文件/文件路径,创建一个空的文件 3.会把FileOutputStream对象指向创建好的文件
public class OutputDemo2 {
public static void main(String[] args) throws IOException {
//1.创建字节输出流的对象
//注意点:如果文件不存在,会帮我们自动创建出来.
// 如果文件存在,会把文件原本内容清空在写入.
FileOutputStream fos = new FileOutputStream("C:\\itheima\\a.txt");
//2,写数据 传递一个整数时,那么实际上写到文件中的,是这个整数在码表中对应的那个字符.
fos.write(98);
fos.write(99);
fos.write(100);
//3,释放资源
fos.close(); //告诉操作系统,我现在已经不要再用这个文件了.已经结束了写入数据操作
}
}
执行结果:文件内显示abc
字节流写数据的三种方式
写数据的方法分类
方法名 | 说明 |
---|---|
void write(int b) | 一次写一个字节数据 写到文件中 |
void write(byte[] b) | 一次写一个字节数组数据 |
void write(byte[] b, int off, int len) | 一次写一个字节数组的部分数据,从off索引开始,写入len个 |
public class OutputDemo4 {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("bytestream\\a.txt");
/*byte [] bys = {97,98,99};
fos.write(bys);*/
byte [] bys = {97,98,99,100,101,102,103};
fos.write(bys,1,2);
fos.close();
}
}
执行结果:a文件里面存放bc
字节流写数据的两个小问题
-
字节流写数据如何实现换行
-
windows:\r\n
-
linux:\n
-
mac:\r
-
-
字节流写数据如何实现追加写入【如果原本存在文件,每次写入数据都会清空之前存在的数据,如果想在原本内容下继续写,则利用追加写操作】
-
构造方法
-
public FileOutputStream(String name,boolean append)
-
public FileOutputStream(File file,boolean append)
-
如果第二个参数为true ,则字节将写入文件的末尾而不是开头
-
public class OutputDemo5 {
public static void main(String[] args) throws IOException {
//第二个参数就是续写开关,如果没有传递,默认就是false,
//表示不打开续写功能,那么创建对象的这行代码会清空文件.
//如果第二个参数为true,表示打开续写功能
//那么创建对象的这行代码不会清空文件.
FileOutputStream fos = new FileOutputStream("bytestream\\a.txt",true);
//fos.write("\r\n");【直接写\r\n成了字符串,不是字节无法添加到文件当中,
利用字符串里的getBytes方法,将字符串存入字节数组中】
fos.write(97);
//能加一个换行
fos.write("\r\n".getBytes());
fos.write(98);
//能加一个换行
fos.write("\r\n".getBytes());
fos.write(99);
//能加一个换行
fos.write("\r\n".getBytes());
fos.write(100);
//能加一个换行
fos.write("\r\n".getBytes());
fos.write(101);
//能加一个换行
fos.write("\r\n".getBytes());
fos.close();
}
}
执行结果:a文件里显示
a
b
c
d
e
public class OutputDemo6 {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
//System.out.println(2/0);
fos = new FileOutputStream("D:\\a.txt");
fos.write(97);
}catch(IOException e){
e.printStackTrace();
}finally {
//finally语句里面的代码,一定会被执行.
if(fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
字节流读数据
-
字节输入流
-
构造方法
-
FileInputStream(String name) FileInputStream(File file) 参数:读取文件的数据源 String name:文件的路径 File file:文件 构造方法的作用: 1.会创建一个FileInputStream对象 2.会把FileInputStream对象指定构造方法中要读取的文件
-
-
字节输入流读取数据的步骤
-
创建字节输入流对象
-
调用字节输入流对象的读数据方法
-
释放资源
-
成员方法
int read()从输入流中读取数据的下一个字节。 当后续没内容是,返回-1 int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。返回值为读取的有效个数 void close() 关闭此输入流并释放与该流关联的所有系统资源。
(一次读一个字节数据)
public class OutputDemo7 {
public static void main(String[] args) throws IOException {
//如果文件存在,那么就不会报错.
//如果文件不存在,那么就直接报错.
FileInputStream fis = new FileInputStream("bytestream\\a.txt");
【假如文件中只有一个a字母】
int read = fis.read();
//一次读取一个字节,返回值就是本次读到的那个字节数据.
//返回的值也就是字符在码表中对应的那个数字.
//如果我们想要看到的是字符数据,那么一定要强转成char
//System.out.println(read);【如果文件里存的是a,则输出的是97数字】
System.out.println((char)read);
//释放资源
fis.close();
}
}
一次读取多个字节
public class OutputDemo8 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("bytestream\\a.txt");
//1,文件中多个字节我怎么办?
/*while(true){
int i1 = fis.read();
System.out.println(i1);
}*/
int b;
while ((b = fis.read())!=-1){
System.out.println((char) b);
}
fis.close();
}
}
案例: 复制文件
public class OutputDemo9 {
public static void main(String[] args) throws IOException {
//创建了字节输入流,准备读数据.
FileInputStream fis = new FileInputStream("C:\\itheima\\a.avi");
//创建了字节输出流,准备写数据.
FileOutputStream fos = new FileOutputStream("bytestream\\a.avi");
int b;
while((b = fis.read())!=-1){
fos.write(b);
}
fis.close();
fos.close();
}
}
思考:如果复制一个超级大文件,采用之前的方法,挨个读,挨个写太慢了。有什么更好的办法
public class OutputDemo10 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("C:\\itheima\\a.avi");
FileOutputStream fos = new FileOutputStream("bytestream\\a.avi");
byte [] bytes = new byte[1024];【相当于一个买鸡蛋的篮子,通过篮子批量往里装进行输送】
int len;//本次读到的有效字节个数 --- 这次读了几个字节
while((len = fis.read(bytes))!=-1){
fos.write(bytes,0,len);
}
fis.close();
fos.close();
}
}
创建个自己数组(容器),使用read一次读取文件中1024个坑位,返回值为有多少个坑位中真正有内容。如果全都没内容,就返回-1
字节缓冲流
另一种方式:提高读和写的效率
BufferedOutputStream 字节缓冲输出流
BufferedInputStream 字节缓冲输入流
-
字节缓冲流介绍
-
lBufferOutputStream:该类实现缓冲输出流.通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用
-
lBufferedInputStream:创建BufferedInputStream将创建一个内部缓冲区数组.当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节
-
-
构造方法:
方法名 说明 BufferedOutputStream(OutputStream out) 创建字节缓冲输出流对象 BufferedInputStream(InputStream in) 创建字节缓冲输入流对象
为什么构造方法需要的是字节流,而不是具体的文件或者路径呢?
字节缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作
读写方法的底层依旧是调用字节流的读写方法
【提供一个储备仓库,提前放入资源】
public class OutputDemo11 {【利用缓冲流一个字节一个字节的拷贝】
public static void main(String[] args) throws IOException {
//就要利用缓冲流去拷贝文件
//创建一个字节缓冲输入流
//在底层创建了一个默认长度为8192的字节数组。
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bytestream\\a.avi"));
//创建一个字节缓冲输出流
//在底层也创建了一个默认长度为8192的字节数组。
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bytestream\\copy.avi"));
int b;
while((b = bis.read()) != -1){
bos.write(b);
}
//方法的底层会把字节流给关闭。
bis.close();
bos.close();
}
}
创建了一个长度为8192的字节数组。
倒手的过程是在内存中进行的,内存的数度很快
package com.itheima.output;
import java.io.*;
public class OutputDemo12 {
public static void main(String[] args) throws IOException {
//缓冲流结合数组,进行文件拷贝
//创建一个字节缓冲输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bytestream\\a.avi"));
【参数传递是字节流,来指定文件路径位置,真正干活的是字节流,而缓冲流只是提供了一个提高效率的功能】
//创建一个字节缓冲输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bytestream\\copy.avi"));
byte [] bytes = new byte[1024];
int len;
while((len = bis.read(bytes)) != -1){
bos.write(bytes,0,len);
}
bis.close();
bos.close();
}
}