** 前言: **
兄弟们看完之后。给个反馈吧。我还是改不掉我的贪玩,拖延症的习惯啊,有的时候一天看短视频就是4,5小时,哎~~
接下来的文章内容来源于。感谢收看
[硅谷学习路线](2021年度全网最全Java学习路线 - 哔哩哔哩 (bilibili.com))
File类
java.io.File类:文件和文件目录路径的抽象表示形式,与平台无关
File 能新建、删除、重命名文件和目录,但 File 不能访问文件内容本身。 如果需要访问文件内容本身,则需要使用输入/输出流。
想要在Java程序中表示一个真实存在的文件或目录,那么必须有一个File对 象,但是Java程序中的一个File对象,可能没有一个真实存在的文件或目录。
File可以表示文件,目录。但是不能读取和写入文件。读取和写入属于IO操作
File类常见的构造器
构造函数 | 描述 |
---|---|
public File(String pathname) | 以pathname为路径创建File对象,可以是绝对路径或者相对路径,如果 pathname是相对路径,则默认的当前java文件相对。 绝对路径:是一个固定的路径,从盘符开始 。 相对路径:是相对于某个位置开始 |
public File(String parent,String child) | 以parent为父路径,child为子路径创建File对象。 |
public File(File parent,String child) | 根据一个父File对象和子文件路径创建File对 |
public class FileTest {
public static void main(String[] args) {
// 第一种构造器
File file1 = new File("D:\\myeclipse");
System.out.println("文件的名字"+file1.getName());
// 第二种构造器
File file2 = new File("D:\\myeclipse","binary");
System.out.println("是否是目录"+file2.isDirectory());
// 第三种
File file3 = new File(file1,"notice.html");
System.out.println("file3文件的大小"+file3.length());
}
}
上面说相对路径
java默认的相对路径
指的就是该项目存放的位置
public class FileTest {
public static void main(String[] args) {
// java的默认相对位置就是当前项目存放的位置
File file4 = new File("pom.xml");
System.out.println(file4.length());
}
}
路径分割符
路径中的每级目录之间用一个路径分隔符隔开。
路径分隔符和系统有关:
windows和DOS系统默认使用“\”来表示
UNIX和URL使用“/”来表示
Java程序支持跨平台运行,因此路径分隔符要慎用。
public static final String separator。根据操作系统,动态的提供分隔符。
File file2 = new File("d:" + File.separator + "atguigu" + File.separator + "info.txt");
File常用方法
方法 | 描述 |
---|---|
public String getAbsolutePath() | 获取绝对路径 |
public String getPath() | 获取路径 |
public String getName() | 获取名称 |
public String getParent() | 获取上层文件目录路径。若无,返回null |
public long length() | 获取文件长度(即:字节数)。不能获取目录的长度。 |
public long lastModified() | 获取最后一次的修改时间,毫秒值 |
public String[] list() | 获取指定目录下的所有文件或者文件目录的名称数组 |
public File[] listFiles() | 获取指定目录下的所有文件或者文件目录的File数组 |
File类的判断方法
方法 | 描述 |
---|---|
public boolean isDirectory() | 判断是否是文件目录 |
public boolean isFile() | 判断是否是文件 |
public boolean exists() | 判断是否存在 |
public boolean canRead() | 判断是否可读 |
File类的创建功能
方法 | 描述 |
---|---|
public boolean createNewFile() | 创建文件。若文件存在,则不创建,返回false |
public boolean mkdir() | 创建文件目录。如果此文件目录存在,就不创建了。 如果此文件目录的上层目录不存在,也不创建。 |
public boolean mkdirs() | 创建文件目录。如果上层文件目录不存在,一并创建 注意事项:如果你创建文件或者文件目录没有写盘符路径,那么,默认在项目 路径下。 |
public boolean delete() | 删除文件或者文件夹 |
删除注意事项:
Java中的删除不走回收站。 要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录
JAVA的IO
每年的谷歌都有IO大会(开放中创新),了解一下 。
java中的IO:
I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于 处理设备之间的数据传输。如读/写文件,网络通讯等。
Java程序中,对于数据的输入/输出操作以“流(stream)” 的 方式进行。
java.io包下提供了各种“流”类和接口,用以获取不同种类的 数据,并通过标准的方法输入或输出数据。
流的分类
按操作数据单位不同分为
字节流(8 bit),字符流(16 bit)
**字节流:**一般用于处理图片,视频等
**字符流:**处理文件。
按数据流的流向不同分为
输入流,输出流
**输入流input:**读取外部数据(磁 盘、光盘等存储设备的数据)到 程序(内存)中。
**输出output:**将程序(内存) 数据输出到磁盘、光盘等存储设 备中。
按流的角色的不同分为
节点流,处理流
**节点流:**表示其他设备直接向内存中进行操作
**处理流:**表示在节点流之上在做一层处理的操作。可以使流的效率提高
Java的IO流共涉及40多个类,实际上非常规则,都是从如下4个 抽象基类派生的。
由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。
下面主要介绍这些实现类
操作步骤
File类的实例化:先找到指定的文件
流实现类的加载文件
读写操作
资源的关闭。确保资源的使用,用完就关闭
InputStream
常用方法
方法 | 描述 |
---|---|
int read() | 从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因 为已经到达流末尾而没有可用的字节,则返回值 -1。 |
int read(byte[] b) | 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。如果因为已 经到达流末尾而没有可用的字节,则返回值 -1。否则以整数形式返回实际读取 的字节数。 |
int read(byte[] b, int off,int len) | 将输入流中最多 len 个数据字节读入 byte 数组。尝试读取 len 个字节,但读取 的字节也可能小于该值。以整数形式返回实际读取的字节数。如果因为流位于 文件末尾而没有可用的字节,则返回值 -1。 |
public void close() throws IOException | 关闭此输入流并释放与该流关联的所有系统资源。 |
示例
这个示例中展示了输入流
讲文件内容输入到内存中,从而在内存中进行打印
public class FileTest {
public static void main(String[] args) {
// java的默认相对位置就是当前项目存放的位置
File file4 = new File("C:\\Users\\HP\\Desktop\\ByteTest.txt");
// 可以看到checked异常处理
try {
InputStream inputStream = new FileInputStream(file4);
System.out.println("开始字节文件输出");
int read = inputStream.read();
while (read != -1) {
System.out.print((char) read);
read = inputStream.read();
}
inputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
FileReader fileReader = new FileReader(file4);
System.out.println("开始字符流输出");
int read = fileReader.read();
while (read != -1) {
System.out.print((char) read);
read = fileReader.read();
}
fileReader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
上面我们同时使用了字节流和字符流对全是英文的内容做处理
接下来我们换成中文试一试。
发现结果变为,字节流产生乱码,字符流可以进行完整打印
Reader
常用的方法
方法 | 描述 |
---|---|
int read() | 读取单个字符。作为整数读取的字符,范围在 0 到 65535 之间 (0x00-0xffff)(2个 字节的Unicode码),如果已到达流的末尾,则返回 -1 |
int read(char[] cbuf) | 将字符读入数组。如果已到达流的末尾,则返回 -1。否则返回本次读取的字符数。 |
int read(char[] cbuf,int off,int len) | 将字符读入数组的某一部分。存到数组cbuf中,从off处开始存储,最多读len个字 符。如果已到达流的末尾,则返回 -1。否则返回本次读取的字符数。 |
public void close() throws IOException | 关闭此输入流并释放与该流关联的所有系统资源。 |
合理的使用上面的方法,即可完成对应的操作
OutputStream
常用方法
方法 | 描述 |
---|---|
void write(int b) | 将指定的字节写入此输出流。write 的常规协定是:向输出流写入一个字节。要写 入的字节是参数 b 的八个低位。b 的 24 个高位将被忽略。 即写入0~255范围的。 |
void write(byte[] b) | 将 b.length 个字节从指定的 byte 数组写入此输出流。write(b) 的常规协定是:应该 与调用 write(b, 0, b.length) 的效果完全相同。 |
void write(byte[] b,int off,int len) | 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。 |
public void flush()throws IOException | 刷新此输出流并强制写出所有缓冲的输出字节,调用此方法指示应将这些字节立 即写入它们预期的目标。 |
public void close() throws IOException | 关闭此输出流并释放与该流关联的所有系统资源。 |
图片的复制示例
package FileTest;
import java.io.*;
public class pictureCope {
public static void main(String[] args) {
// 创建以file表示指定的图片
File file = new File("C:\\Users\\HP\\Desktop\\mr.jpg");
// 再次创建file,此时指定的文件不存在。
// 默认当指定不存在的文件会进行创建
File file01 = new File("C:\\Users\\HP\\Desktop\\mr01.jpg");
// 因为是图片等需要使用字节流
try {
// 字节流的输入流
FileInputStream fileInputStream = new FileInputStream(file);
FileOutputStream fileOutputStream = new FileOutputStream(file01);
// 先去进行一点一点的读取,读取的时候进行传入
int read = fileInputStream.read();
while (read !=-1){
fileOutputStream.write(read);
read = fileInputStream.read();
}
fileInputStream.close();
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e){
e.getMessage();
}
}
}
Writer
方法 | 描述 |
---|---|
void write(int c) | 写入单个字符。要写入的字符包含在给定整数值的 16 个低位中,16 高位被忽略。 即 写入0 到 65535 之间的Unicode码。 |
void write(char[] cbuf) | 写入字符数组。 |
void write(char[] cbuf,int off,int len) | 写入字符数组的某一部分。从off开始,写入len个字符 |
void write(String str) | 写入字符串。 |
void write(String str,int off,int len) | 写入字符串的某一部分。 |
void flush() | 刷新该流的缓冲,则立即将它们写入预期目标。 |
public void close() throws IOException | 关闭此输出流并释放与该流关联的所有系统资源。 |
示例
public class ReadTest {
public static void main(String[] args) {
File file = new File("C:\\Users\\HP\\Desktop\\ByteTest.txt");
try {
FileWriter fileWriter = new FileWriter(file);
System.out.println("指定写入的内容:");
fileWriter.write("加油华为,5G领导者");
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
根据结果发现,确实写入了
但是内容被覆盖了。想要不覆盖。在构造函数中设置参数
FileWriter fileWriter = new FileWriter(file,true);
缓冲流
为了提高数据读写的速度,Java API提供了带缓冲功能的流类,
在使用这些流类 时,会创建一个内部缓冲区数组,缺省使用8192个字节(8Kb)的缓冲区。
缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为:
字节流对应的:BufferedInputStream 和 BufferedOutputStream
字符流对应的:BufferedReader 和 BufferedWriter
示例
在图片复制基础上进行添加代码
package FileTest;
import java.io.*;
public class pictureCope {
public static void main(String[] args) {
// 创建以file表示指定的图片
File file = new File("C:\\Users\\HP\\Desktop\\mr.jpg");
// 再次创建file,此时指定的文件不存在。
// 默认当指定不存在的文件会进行创建
File file01 = new File("C:\\Users\\HP\\Desktop\\mr02.jpg");
// 因为是图片等需要使用字节流
try {
// 字节流的输入流
FileInputStream fileInputStream = new FileInputStream(file);
// 字节的输出流
FileOutputStream fileOutputStream = new FileOutputStream(file01);
// 添加缓冲流
// 输入流的缓冲,讲输入流带入
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
// 先去进行一点一点的读取,读取的时候进行传入
int read = bufferedInputStream.read();
while (read !=-1){
bufferedOutputStream.write(read);
read = bufferedInputStream.read();
}
// 先关闭最外层的缓冲流,在关闭内部的节点流
bufferedInputStream.close();
bufferedOutputStream.close();
fileInputStream.close();
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e){
e.getMessage();
}
}
}
根据结果确实实现功能。缓冲流可以提高效率
注意
关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也 会相应关闭内层节点流
如果是带缓冲区的流对象的close()方法,不但会关闭流,还会在关闭流之前刷 新缓冲区,关闭后不能再写出
转换流
转换流提供了在字节流和字符流之间的转换
Java API提供了两个转换流:
- InputStreamReader:将InputStream转换为Reader
- OutputStreamWriter:将Writer转换为OutputStream
字节流中的数据都是字符时,转成字符流操作更高效。
InputStreamReader
实现将字节的输入流按指定字符集转换为字符的输入流。
构造函数
public InputStreamReader(InputStream in)
public InputSreamReader(InputStream in,String charsetName)
第二种指定类转换的字符编码
示例
// 讲字节流的输入流转换为字符流的输入流
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
OutputStreamWriter
实现将字符的输出流按指定字符集转换为字节的输出流。
构造函数
public OutputStreamWriter(OutputStream out)
public OutputSreamWriter(OutputStream out,String charsetName)
示例
// 讲字节流的输出流转换为字符流的输出流
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
字符编码
编码表的由来
计算机只能识别二进制数据,早期由来是电信号。为了方便应用计算机,让它可以识 别各个国家的文字。就将各个国家的文字用数字来表示,并一一对应,形成一张表。 这就是编码表。
常见的编码表
ASCII:美国标准信息交换码。 用一个字节的7位可以表示。
ISO8859-1:拉丁码表。欧洲码表 用一个字节的8位表示。
GB2312:中国的中文编码表。最多两个字节编码所有字符
GBK:中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码
Unicode:国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的 字符码。所有的文字都用两个字节来表示。
UTF-8:变长的编码方式,可用1-4个字节来表示一个字符。
GBK的问题解决
因为GBK表示中文的字符编码,一个字符最多使用两个字节。
但是当计算机中存在两个字节的时候。
如何判断它算是一个字符还是两个字符
通过第一个字节上面的其实数组是0或1。0表示一个字符1表示1两个字符
Unicode的问题和解决
这一段可以去看一看硅谷的课程,讲的特别生动。
其他流
流的分布存在很多,感兴趣可以多了解亿点点
标准输入输出流
System.in和System.out分别代表了系统标准的输入和输出设备
默认输入设备是:键盘,输出设备是:显示器
System.in的类型是InputStream
System.out的类型是PrintStream,其是OutputStream的子类 FilterOutputStream 的子类
在最开始我们经常使用的输入输出
Scanner sc = new Scanner(System.in);
System.out.println("请输入信息");