File类和IO流
前言
本文浅谈File类和IO流
提示:以下是本篇文章正文内容,下面案例可供参考
一、File类
1.1File类的介绍
File这个类是sun公司给JAVA开发者提供的一个处理文件和文件夹的类
路径问题:【重要】
404 就是找不到当前文件的路径
相对路径:
得有参照物
我在你隔壁,参照物是你
相对路径:
./代表当前目录
../相当于当前目录的上一级目录
../../相当于当前目录的上两级目录
../../../相当于当前目录的上三级目录
绝对路径:
磁盘的根路径
C:\User\Mriacles21\Desktop\ZZ2109\day19\code
XXX在我前面坐,这个是相对路径还是绝对路径?相对路径
个人建议,咱们以后再写路径: 使用 /
① ./ 支持Windows和Linux
② .\ 只支持Windows系统,不支持Linux系统
File类的构造方法:
File(String pathname);//通过将给定的路径名字符串创建新的File实例。
File(String parent,String child);//从父路径名字符串和子路径名字符串创建新的 File实例。
C:\User\Mriacles21\Desktop\zz2109\day19\code
根据文件指定的父级目录,和子目录创建一个文件对象或者文件夹对象
File(File file,String chiles);//从父抽象路径名和子路径名字符串创建新的 File实例。
File(URI uri);//通过将给定的 file :URI转换为抽象路径名来创建新的File实例
1.2使用File类创建文件或文件夹
开发中,我们以后会使用这些方法做文件上传,比如开发中头像上传
很多网站和app都是实名认证的,现在需要上传身份证正反面,这个就是文件上传的功能
需要用到以下方法
bolean createNewFile();创建文件方法,返回值是布尔类型的数据
【注意事项】
① 操作的文件的路径不存在,返回false
② 硬盘坏了,报错
③ 文件已经存在的时候,就返回false
boolean mkdir();
boolean mkdirs();
通过file对象,创建的文件夹是保存的路径地址
boolean renameTo(File file);
通过文件对象,重命名 移动等
import java.io.File;
import java.io.IOException;
public class Demo1 {
public static void main(String[] args) throws IOException {
File file = new File("d:/test/8.txt");
//file.createNewFile()这个方法有可能出现异常
//使用java代码创建的一个文件
file.createNewFile();
File file1 = new File("d:/test/bbb");
boolean mkdir = file1.mkdir();//只能创建一级目录
System.out.println(mkdir);
File file2 = new File("d:/test/aaa/bbb/ccc/eee");
System.out.println(file2.mkdirs());//创建多层目录 层级比较深了
File file3 = new File("d:/test/1.txt");
File file4 = new File("D:/test/aaa/重命名并移动的文本文档.txt");
System.out.println(file3.renameTo(file4));//移动并重命名
}
}
1.3File删除文件或者文件夹
boolean delete();//立即删除
void deleteOnExit();//程序退出以后才删除对应的文件或文件夹
删除:硬删除,直接从磁盘上删除,不会保留到回收站
import java.io.File;
public class Demo2 {
public static void main(String[] args) {
File file = new File("d:/test/1.txt");
System.out.println(file.delete());
File file1 = new File("d:/test/2.txt");
file1.deleteOnExit();
System.exit(0);
}
}
1.4File对象的一些判断方法
boolean isFile();//是不是普通文件
boolean isDirectory();//是不是文件夹(目录)
boolean isHidden();//是不是隐藏文件
boolean isAbsolute();//是不是绝对路径
boolean exits();//对应的文件或者文件夹是否存在
import java.io.File;
public class Demo3 {
public static void main(String[] args) {
/*
* boolean isFile();是不是普通文件
* boolean isDirectory();是不是文件夹(目录)
* boolean isHidden();是不是隐藏文件
* boolean isAbsolute();是不是绝对路径
* boolean exits();对应的文件或者文件夹是否存在
* */
System.out.println(new File("d:/test/1.txt").isFile());//true
System.out.println(new File("d:/test/1.txt").isDirectory());//false
System.out.println(new File("d:/test/aaa").isDirectory());//true
System.out.println(new File("d:/test/1.txt").isHidden());//false
System.out.println(new File("d:/test/aaa/bbb").isAbsolute());//true
System.out.println(new File("./Demo3").isAbsolute());//false
System.out.println(new File("d:/test/1.txt").exists());//true
}
}
1.5返回String类型的数据的方法
String getName();//获取文件或者文件夹得名字
String getPath();//获取当前创建File对象的路径
String getParent();//获取当前文件对象的父级目录
String getAbsolutePath();//获取当前文件的绝对路径
import java.io.File;
public class Demo4 {
public static void main(String[] args) {
/**
* String getName();获取文件或者文件夹的名字
*
* String getPath();获取当前创建File对象的路径
*
* String getParent();获取当前文件对象的父级目录
*
* String getAbsolutePath();获取绝对路径
*
* */
String path = "d:/test/1.txt";
File file = new File(path);
System.out.println(file.getName());// 1.txt
System.out.println(file.getPath());// d:/test/1.txt
System.out.println(file.getParent());// d:\test
File file1 = new File("./");
System.out.println(file1.getAbsolutePath());// D:\idea_workspace\day01_xkh\.
}
}
1.6返回是long类型数据的方法
long length();//获取文件占用硬盘的字节数
long lastModified();//获取当前文件最后的修改时间,这个时间是时间戳
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Demo6 {
public static void main(String[] args) {
/**
* long length();获取文件占用硬盘的字节数
* long lastModified();获取当前文件最后的修改时间,这个时间是时间戳
*/
File file = new File("d:/test/1.txt");
System.out.println(file.length());//返回的是文件占用硬盘的字节数
//一个英文字符占1个字节 一个中文字符占用2个字节,还有可能占用3个字节
System.out.println(file.lastModified());//获取文件最后一次修改完成的时间
//该时间是一个时间戳
//1629128092140 从1970年的1月1日0:0:0到 2021年8月16日 23:37:11
//扩展
//时间戳 这个数值换算成咱们时间,看不懂
//对客户不友好,怎么办?换算成北京时间
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
String format = simpleDateFormat.format(new Date(file.lastModified()));
System.out.println(format);//2021-08-16 23:34:52
}
}
1.7文件列表方法
static File[] listRoots();只适用Windows系统。列出可用的文件系统根。
String[] list();//获取当前文件夹对象下面的所有子文件和子文件夹对象
import java.io.File;
public class Demo7 {
public static void main(String[] args) {
File[] files = File.listRoots();
for (File file : files) {
System.out.println(file);
}
System.out.println("=======================");
String path = "c:/Program Files/Java/jdk1.8.0_241";
File file = new File(path);
String[] list = file.list();
for (String s : list) {
System.out.println(s);
}
}
}
二、IO流
IO流的主要用于文件的读写,其实电脑的功能就是在读写
2.1缓冲的概念
看视频有点卡,等他一下,再缓冲一会儿
顺丰快递
上海===》郑州
快递有物流中转基地,到时间点,攒够以后再发
计算机读,存。计算机的cpu通过内存读取硬盘中的数据,不是一个字节一个字节读取的。
每次大概从硬盘中读取4kb。
为什么要读取4kb?
1.提高读取和存储的效率
2.保护磁盘
Io流在操作文件的时候:
读取和写入数据,如果按照一个字节或者一个字符来读取和写入的话,效率是非常低的,可以采用缓冲的概念。
1.读取数据,按照CPU通过内存区读取硬盘上的数据,读取的数据是4kb,缓冲到内存区,再从内存区取出来
硬盘-》内存-》数据展示
2.写入。先把数据放到内存中,然后再把内存写到磁盘中
数据-》内存-》磁盘
Io流分为两个流,一个读的流,一个写的流
2.2IO流的分类
参照物是内存,可以理解为是当前的应用程序(demo)
input 输入 从硬盘读取数据存入到了内存中,这叫输入
output 输出 从内存中写入数据到磁盘中,这叫输出
输入流(读)和输出流(写)
两种处理方式:
字节流:
按照字节为单位,处理当前文件
字符流:
首先按照字节读取或者写入数据,但是在操作过程中会有一个解码过程。如果解码不成功,就意味着咱们读取数据和写入数据失败了。容易失败
java给咱们提供了
输入字节流
InputStream 它有一个子类 FileInputStream
输出字节流
OutputStream 它有一个子类 FileOutputStream
输入字符流
FileReader
输出字符流
FileWriter
2.3缓冲流
所有的缓冲流都是没有读写功能的,一般作用于输入流和输出流上
字节输入缓冲流
BufferedInputStream
字节输出缓冲流
BufferedOutputStream
字符输入缓冲流
BufferedReader
字符输出缓冲流
BufferedWriter
2.3.1字节输入输出流
字节输入流代码如下(示例):
import java.io.*;
//FileInputStream 字节输入流
//从硬盘读取数据写入到内存中
//把D:/test/1.txt文件的内容,读取到咱们的内存中,内存就是咱们的应用程序
//也就是我们的demo
public class Demo2 {
public static void main(String[] args) throws IOException {
//1.在硬盘中找到对应的文件(里面有数据,等会把这个数据读取到内存中)
File file = new File("d:/test/2.txt");
//2.创建一个FileInputStream文件输入流对象
//FileInputStream这个类不具备缓冲的功能
FileInputStream fis = new FileInputStream(file);
//3.BufferedInputStream 给FileInputStream添加了一个缓冲的功能,让他们执行的效率更高
BufferedInputStream bis = new BufferedInputStream(fis);
//4.将内容读取到数组里面,这个数组就是缓冲数组
//从该输入流读取最多4096字节的数据到字节数组中。此方法将阻塞,直到某些输入可用。起到一个缓冲的作用
//写入到内存中在我们的代码数组中
byte[] buf = new byte[1024 * 4];
//buf 是字节数组,该数组统称1024的倍数,缓冲数组,用来保存读取到的数据
//输入流:从硬盘-》内存(数组)
int length = -1;
while ((length = bis.read(buf)) != -1){
System.out.println(length);
System.out.println(new String(buf,0,length));
}
//不等于-1,就证明没有读完这个数据,while循环就不能停止
//为了让大家看一下我确实从1.txt读取出来了,我将字符数组重新构造成为一个新的字符串并打印了
//6.因为IO流会一直消耗电脑资源的,所以用完了,要关闭流
bis.close();
fis.close();
}
}
字节输出流代码如下(示例):
import java.io.*;
//首先创建一个空的文件,然后写入数据到这个空文件上面
//从内存写入数据到文件中
//输出流
public class Demo3 {
public static void main(String[] args) throws IOException {
//从内存写入磁盘上面
//1.创建对应的File类对象,写入数据到2.txt
File file = new File("d:/test/3.txt");
//2.创建对应的字节输出流对象
FileOutputStream fos = new FileOutputStream(file);
//3.创建对应的字节缓冲输出流对象
BufferedOutputStream bos = new BufferedOutputStream(fos);
//4.写入数据
//现在是字符串,怎么把字符串转换为字节数组呢?
byte[] bytes = "渔得鱼心满意足,樵的樵眼笑眉舒".getBytes();
//这个方法写一个字节数组到文件中
bos.write(bytes);
//5.关闭资源
bos.close();
fos.close();
}
}
综合案例
复制一个文件到另外一个地方代码如下(示例):
//复制一个文件到另外一个地方
import java.io.*;
public class Demo4 {
public static void main(String[] args) throws IOException {
//复制一个文件到另外一个文件夹下面
copy1();
System.out.println("==================")
copy2();
}
/*
* 带有缓冲流的复制
* */
public static void copy1() throws IOException {
//获取当前系统的时间,该方法返回的是一个long类型的数据,叫做时间戳
long start = System.currentTimeMillis();
//首先你得有一个视频源文件,将整个视频源文件从磁盘上读取到内存中
//然后再从内存中将文件写入到另外一个文件上
//1.创建对应的输入输出缓冲流对象
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("D:/test/1.avi")));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("c:/work/1.avi")));
//2.准备字节数组,目的是作为缓冲区
byte[] buf = new byte[1024 * 4];
//关于缓冲区,我的建议是写8 * 1024 或者4 * 1024
//要考虑运行内存和性价比
int length = -1;
//3.从磁盘读取到内存中,再从内存中写入到磁盘上
while((length = bis.read(buf)) != -1){
bos.write(buf,0,length);
}
//4.关闭流
bis.close();
bos.close();
long end = System.currentTimeMillis();//获取当前系统的时间
System.out.print("该方法花费了:");
System.out.print(end - start);
System.out.print("毫秒");
}
/*
* 缓冲流,可以提高咱们读写的执行效率
* 下面的是不带缓冲流的案例,可以看看程序的耗时
* */
public static void copy2() throws IOException {
long start = System.currentTimeMillis();
//创建对应的输入输出流对象
FileInputStream fis = new FileInputStream(new File("d:/test/1.avi"));
FileOutputStream fos = new FileOutputStream(new File("c:/work/2.avi"));
//这个没有带缓冲流
//没有带缓冲流,还需要缓冲数组吗?不需要
int length = -1;
//将磁盘上的文件数据读入到内存中,再从内存中把文件数据写入到磁盘中
while((length = fis.read()) != -1){
fos.write(length);
//一个字节循环一次,带缓冲的是该方法的4096倍
}
//关闭流
fis.close();
fos.close();
long end = System.currentTimeMillis();
System.out.print("该方法花费了:");
System.out.print(end - start);
System.out.print("秒");
}
}
2.3.2字符输入输出流
字符输入流代码如下(示例):
import java.io.*;
//字符输入流 Reader
//和字节输入流的功能类似,但是中间多了一个解码的过程,有可能出现问题
//从磁盘上面读取一个文件里面的内容到内存中
public class Demo5 {
public static void main(String[] args) throws IOException {
//1.创建File对象
File file = new File("D:/test/5.txt");
//2.创建一个字符输入流对象
FileReader fr = new FileReader(file);
//3.创建对应的缓冲字符输入流对象
BufferedReader br = new BufferedReader(fr);
//4.读取文件到内存中
//int read();读取一个字符
//int read(char[] chars);缓冲数组,将数据读取到这个缓冲数组中
//String readLine();读取一行数据
char[] chars = new char[1024];
int length = br.read(chars);
System.out.println(new String(chars));//借助于String类打印一下char数组中的东西
//5.关闭流
br.close();
fr.close();
}
}
字符输出流代码如下(示例):
import java.io.*;
//字符输出流
//将内存的数据写入到磁盘上面
public class Demo6 {
public static void main(String[] args) throws IOException {
//1.创建一个File对象
File file = new File("D:/test/6.txt");
//2.创建字符输出流对象
FileWriter fw = new FileWriter(file);
//3.创建对应的缓冲字符输出流对象
BufferedWriter bw = new BufferedWriter(fw);
//4.写入字符到文件中
//bw.write("小yu别错过");
//写入字符串的一部分
bw.write("春娇与志明,泡沫",1,4);//娇与志明
bw.newLine();//换行写数据
bw.write("辞九门回忆");
bw.newLine();//换行写数据
bw.write("星辰大海");
//5.关闭流
bw.close();
fw.close();
}
}
【注意事项】
字符流一般不会用作图片 音频 视频的读写操作!!!有可能在转码的时候出现问题
图片 音频 视频的读写操作都是使用字节流
特别是以后文件上传的时候,比如上传头像,绝对不能使用字符流