File类和IO流的字节流(1)
一、File类
1.File,是文件和目录路径名的抽象表示
2.File只关注文件本身的信息(文件名、可读、可写),而不能操作文件里面的内容
3.File类 – 表示文件或文件夹,不能对文件里的数据进行操作
4.对文件里的数据进行操作的是:IO流
1.File类的常用方法
import java.io.File;
import java.text.SimpleDateFormat;
public class Test01 {
public static void main(String[] args) {
//创建File对象
File file = new File("D:\\图库\\海底世界.jpg");
System.out.println("获取文件名:" + file.getName());
System.out.println("获取文件大小(字节):" + file.length());
System.out.println("获取是否可读:" + file.canRead());
System.out.println("获取是否可写:" + file.canWrite());
System.out.println("获取是否隐藏:" + file.isHidden());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy--MM--dd HH--mm--ss");
String dateTime = sdf.format(file.lastModified());
System.out.println("获取最后的修改时间:" + dateTime);
}
}
2.研究绝对路径和相对路径
绝对路径:指定了盘符的具体路径
相对路径:相对于此项目下的路径
import java.io.File;
public class Test02 {
public static void main(String[] args) {
//创建File对象
File file = new File("IO笔记.txt");
//相对路径:IO笔记.txt
System.out.println("相对路径:" + file.getPath());
//绝对路径: F:\2211workspace\MyDay22\IO笔记.txt
System.out.println("绝对路径: " + file.getAbsolutePath());
}
}
3.通过程序,判断指定路径的文件是否存在,如果不存在,则创建该文件下面按各种情况来解决该问题
1.目录已存在的情况
import java.io.File;
import java.io.IOException;
public class Test01 {
public static void main(String[] args) throws IOException {
File file = new File("file01\\gl.txt");
if (!file.exists()) {//判断文件是否存在
//创建文件
file.createNewFile();
}
}
}
2.有一个层级的目录不存在的情况
import java.io.File;
import java.io.IOException;
public class Test02 {
public static void main(String[] args) throws IOException {
File file = new File("file\\gl.txt");
//file01
File parentFile = file.getParentFile();
if (!parentFile.exists()) {//判断文件夹是否存在
//创建一层文件夹
parentFile.mkdir();
}
if (!file.exists()) {//判断文件是否存在
//创建文件
file.createNewFile();
}
}
}
3.有多个层级的目录不存在的情况
import java.io.File;
import java.io.IOException;
public class Test03 {
public static void main(String[] args) throws IOException {
File file = new File("file01\\file02\\file03\\gl.txt");
//file01\\file02\\file03
File parentFile = file.getParentFile();
if (!parentFile.exists()) {//判断文件夹是否存在
//创建多层文件夹
parentFile.mkdirs();
}
if (!file.exists()) {//判断文件是否存在
//创建文件
file.createNewFile();
}
}
}
4.输出指定目录下的所有文件信息(只考虑当前目录,不考虑子目录)
import java.io.File;
public class Test01 {
public static void main(String[] args) {
File file = new File("F:\\2211workspace");
//解决方案1:
//获取到该文件夹下所有的文件名
//String[] list = file.list();
//for (String str : list) {
// System.out.println(str);
//}
//解决方案2:
//获取到该文件夹下所有的File对象
File[] listFiles = file.listFiles();
for (File f : listFiles) {
System.out.println(f.getName() + "---" + f.canRead());
}
}
}
1.要求只输出文件后缀名为java的文件
import java.io.File;
public class Test02 {
public static void main(String[] args) {
File file = new File("F:\\2211workspace\\MyDay06");
//解决方案1:
//获取到该文件夹下所有的文件名
// String[] list = file.list();
// for (String str : list) {
// if (str.endsWith(".class")) {
// System.out.println(str);
// }
// }
//解决方案2:
//获取到该文件夹下所有的File对象
File[] listFiles = file.listFiles();
for (File f : listFiles) {
String name = f.getName();
if (f.isFile() && name.endsWith(".java")) {
System.out.println(name);
}
}
}
}
2.根据API的过滤器来完成该功能
import java.io.File;
import java.io.FilenameFilter;
public class Test03 {
public static void main(String[] args) {
File file = new File("F:\\2211workspace\\MyDay06");
File[] listFiles = file.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
//dir -- new File("C:\\飞秋共享");
//name -- 遍历的文件名
//创建File对象 -- C:\\飞秋共享\\遍历的文件名
File f = new File(dir, name);
if (f.isFile() && name.endsWith(".java")) {
return true;
}
return false;
}
});
for (File f : listFiles) {
System.out.println(f.getName());
}
}
}
3.需求继续跟进,列出当前目录及子目录中jpg的文件信息(递归)
import java.io.File;
public class Test04 {
public static void main(String[] args) {
File file = new File("D:\\图库");
scannerFile(file,".jpg");
}
public static void scannerFile(File file, String suffix) {
File[] listFiles = file.listFiles();
for (File f : listFiles) {
if (f.isDirectory()) {//文件夹
scannerFile(f, suffix);
}else if (f.isFile()) {//文件
String name = f.getName();
if (name.endsWith(suffix)) {
System.out.println(name + "--" + f.getAbsolutePath());
}
}
}
}
}
二、IO流
1.理解:
I - in - 输入流
O - out- 输出流
流 - 像水流一样传输数据
注意:站在程序的角度去理解输入输出应用场景:通过程序处理文件里的内容
2.分流:
按照方向分:输入流、输出流
按照单位分:字节流、字符流
按照功能分:基础流/节点流、处理流
注意:处理流往往包含了基础流,让流的功能更加强大
计算机存储单位:
1024B = 1Kb
1024kb = 1KB
1024Mb = 1Gb
1024Gb = 1Tb
1024Tb = 1Pb
三、利用文件字节输出流 向文件写入数据
1.文件存在的情况下
import java.io.FileOutputStream;
import java.io.IOException;
public class Test01 {
public static void main(String[] args) throws IOException {
//1.创建流对象
FileOutputStream fos = new FileOutputStream("ggc.txt");
//2.写入数据
//fos.write(97);
//fos.write("abcdef".getBytes());//写入字节数组
fos.write("abcdef".getBytes(), 1,3);//写入字节数组、偏移量、长度
//3.关闭资源
fos.close();
}
}
2.文件不存在的情况下
经验:所有的输出流,当文件不存在时都会创建文件
3.在末尾追加内容
import java.io.FileOutputStream;
import java.io.IOException;
public class Test02 {
public static void main(String[] args) throws IOException {
//1.创建流对象+ 在末尾追加内容
FileOutputStream fos = new FileOutputStream("ggc.txt",true);
//2.写入数据
fos.write("abcdefgh".getBytes());//写入字节数组
//3.关闭资源
fos.close();
}
}
4.积极处理异常
import java.io.FileNotFoundException;
/**
* 知识点:利用文件字节输出流 向文件写入数据
*
* 需求:利用文件字节输出流 向文件写入数据
* 1)文件存在的情况下
* 2)文件不存在的情况下
* 经验:所有的输出流,当文件不存在时都会创建文件
* 3)在末尾追加内容
*/
import java.io.FileOutputStream;
import java.io.IOException;
public class Test03 {
public static void main(String[] args) {
//1.创建流对象+ 在末尾追加内容
FileOutputStream fos = null;
try {
//1.创建流对象+ 在末尾追加内容
fos = new FileOutputStream("ggc.txt",true);
//2.写入数据
fos.write("abcdefgh".getBytes());//写入字节数组
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//3.关闭资源
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
四、利用文件字节输入流 读取文件里的数据
1.文件存在的情况下,并且一个字节一个字节的读取
import java.io.FileInputStream;
import java.io.IOException;
public class Test04 {
public static void main(String[] args) throws IOException {
//1.创建流对象
FileInputStream fis = new FileInputStream("ggc.txt");
//2.读取数据
//read() -- 读取一个字节,如果读取到文件末尾则返回-1
int read = fis.read();
System.out.println((char)read);
read = fis.read();
System.out.println((char)read);
read = fis.read();
System.out.println((char)read);
read = fis.read();
System.out.println(read);
fis.close();
}
}
2.一个字节一个字节循环读取
import java.io.FileInputStream;
import java.io.IOException;
public class Test05 {
public static void main(String[] args) throws IOException{
//1.创建流对象
FileInputStream fis = new FileInputStream("ggc.txt");
//2.读取数据
//read() -- 读取一个字节,如果读取到文件末尾则返回-1
int read;
while ((read = fis.read()) != -1) {
System.out.println((char)read);
}
//3.关闭资源
fis.close();
}
}
3.文件不存在的情况下
经验:所有的输入流,当文件不存在都会报FileNotFoundException(文件文找到异常)
4.指定字节数组的循环读取
import java.io.FileInputStream;
import java.io.IOException;
public class Test06 {
public static void main(String[] args) throws IOException {
//1.创建流对象
FileInputStream fis = new FileInputStream("ggc.txt");
//2.读取数据
//read(bs) -- 读取bs数组长度的数据,将数据存入到bs中并返回有效字节数,如果读取到文件末尾则返回-1
byte[] bs = new byte[1024];
int len;
while ((len = fis.read(bs)) != -1) {
//将bs字节数组转换为字符串,从第0个下标开始转换len个长度的字节数据
System.out.println(new String(bs,0,len));
}
//3.关闭资源
fis.close();
}
}
5.积极处理异常
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Test07 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
//1.创建流对象
fis = new FileInputStream("ggc.txt");
//2.读取数据
//read(bs) -- 读取bs数组长度的数据,将数据存入到bs中并返回有效字节数,如果读取到文件末尾则返回-1
byte[] bs = new byte[1024];
int len;
while ((len = fis.read(bs)) != -1) {
//将bs字节数组转换为字符串,从第0个下标开始转换len个长度的字节数据
System.out.println(new String(bs,0,len));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//3.关闭资源
if(fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
6.拷贝文本文件
思路:读取源文件,写入目标文件
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Copy01 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("IO笔记.txt");
FileOutputStream fos = new FileOutputStream("copy.txt");
int read;
while ((read = fis.read()) != -1) {
fos.write(read);
}
fis.close();
fos.close();
}
}
7.拷贝视频文件
读取源文件,写入目标文件
方案一
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Copy02 {
public static void main(String[] args){
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("测试视频.mp4");
fos = new FileOutputStream("copy.mp4");
byte[] bs = new byte[2048];
int len;
while ((len = fis.read(bs)) != -1) {
fos.write(bs,0,len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
方案二
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Copy03 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("测试视频.mp4");
FileOutputStream fos = new FileOutputStream("copy.mp4");
byte[] bs = new byte[2048];
int len;
while ((len = fis.read(bs)) != -1) {
fos.write(bs,0,len);
}
fis.close();
fos.close();
}
}
方案三
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Copy04 {
public static void main(String[] args){
try (FileInputStream fis = new FileInputStream("测试视频.mp4");
FileOutputStream fos = new FileOutputStream("copy.mp4");){
byte[] bs = new byte[1024];
int len;
while((len = fis.read(bs)) != -1){
fos.write(bs, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
五、利用带有缓冲区的字节输出流 向文件写入数据
1.文件存在的情况下
2.文件不存在的情况下
经验:所有的输出流,当文件不存在时都会创建文件
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test01 {
public static void main(String[] args) throws IOException {
//1.创建流的对象
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("ggc.txt"));
//2.写入数据
bos.write("abcdefgh".getBytes());
//3.关闭资源
bos.close();
}
}
3.在末尾追加内容
经验:考虑基础流的构造方法
4.积极处理异常
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test02 {
public static void main(String[] args){
BufferedOutputStream bos = null;
try {
//1.创建流的对象
bos = new BufferedOutputStream(new FileOutputStream("ggc.txt"));
//2.写入数据
bos.write("abcdefgh".getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//3.关闭资源
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
5.研究带有缓冲区的字节输出流为什么效率高?
效率高:减少了程序与硬盘交互的次数
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test03 {
public static void main(String[] args) throws IOException{
//fos与文件交互了3次
FileOutputStream fos = new FileOutputStream("ggc.txt");
fos.write("abc".getBytes());//写入文件
fos.write("def".getBytes());//写入文件
fos.write("ghi".getBytes());//写入文件
fos.close();
//bos与文件交互了1次
//创建带有缓冲区的字节输出流 --- 默认缓冲区为:byte[] buf = new byte[8192];
// BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("ggc.txt")); bos.write("abc".getBytes());//写入缓冲区
// bos.write("def".getBytes());//写入缓冲区
// bos.write("ghi".getBytes());//写入缓冲区
// bos.flush();//将数组中的数据全部刷新到文件中(就算不刷新,关闭流的时候也刷新了)
// bos.close();//将数组中的数据全部写入文件中
//创建带有缓冲区的字节输出流 --- 自定义缓冲区为:byte[] buf = new byte[2048];
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("ggc.txt"),2048);
bos.write("zxc".getBytes());//写入缓冲区
bos.write("sdf".getBytes());//写入缓冲区
bos.write("ryy".getBytes());//写入缓冲区
bos.flush();//将数组中的数据全部刷新到文件中(就算不刷新,关闭流的时候也刷新了)
bos.close();//将数组中的数据全部写入文件中
}
}
六、利用带有缓冲区的字节输入流 读取文件中的数据
1.带有缓冲区的字节输入流使用
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class Test04 {
public static void main(String[] args) throws IOException {
//1.创建流对象 -- 默认缓冲区:byte[] buf = new byte[8192];
// BufferedInputStream bis = new BufferedInputStream(new FileInputStream("hhy.txt"));
//1.创建流对象 -- 自定义缓冲区:byte[] buf = new byte[2048];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("ggc.txt"),2048);
//2.读取数据
byte[] bs = new byte[1024];
int len;
while ((len = bis.read(bs)) != -1) {
System.out.println(new String(bs, 0, len));
}
//3.关闭资源
bis.close();
}
}
2.拷贝视频文件
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Copy {
public static void main(String[] args) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("测试视频.mp4"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.mp4"));
byte[] bs = new byte[1024];
int len;
while ((len = bis.read(bs)) != -1) {
bos.write(bs, 0, len);
}
bis.close();
bos.close();
}
}
七、字节流总结
应用场景:处理二进制文件(图片、音频、视频)
abstract class InputStream --- 字节输入流的基类(抽象类)
abstract class OutputStream -- 字节输出流的基类(抽象类)
class FileInputStream extends InputStream --- 文件字节输入流
class FileOutputStream extends OutputStream - 文件字节输出流
class FilterInputStream extends InputStream --- 过滤器字节输入流
class FilterOutputStream extends OutputStream - 过滤器字节输出流
class BufferedInputStream extends FilterInputStream --- 带有缓冲区的字节输入流
class BufferedOutputStream extends FilterOutputStream - 带有缓冲区的字节输出流
缓冲区大小为:8192字节