Java基础学习
- 一、File
- 1.1 File详情
- 1.2 File常见的成员方法
- 1.2.1 判断获取
- 1.2.2 创建删除
- 1.2.3 获取遍历
- 二、IO流
- 2.1 IO流体系
- 2.2 FileOutputStream
- 2.2.1 FileOutputStream写数据的3种方式
- 2.2.2 FileOutputStream换行写:
- 2.2.3 FileOutputStream续写
- 2.3 FilelnputStream
- 拷贝文件
- 拷贝升级版(一次读取多个字节)
- 2.4 异常处理细节版
- 2.5 字符集
- 2.5.1 计算机的存储规则(英文)
- 2.5.2 计算机的存储规则 GBK--->(英文)
- 2.5.3 计算机的存储规则 GBK--->(汉字)
- 2.5.4 计算机的存储规则(英文)(Unicode )
- 2.5.5 计算机的存储规则(中文)(Unicode )
- 为什么会出现乱码
- Java中编码的方法
- Java中解码的方法
- 2.6 字符流
- 2.6.1 FileReader
一、File
- File对象就表示一个路径,可以是文件的路径、也可以是文件夹的路径
- 这个路径可以是存在的,也允许是不存在的
1.1 File详情
方法名称 | 说明 |
---|---|
public File(String pathname) | 根据文件路径创建文件对象 |
public File(String parent,String child) | 根据父路径名字符串和子路径名字符串创建文件对象 |
public File(File parent,String child) | 根据父路径对应文件对象和子路径名字符串创建文件对象 |
绝对路径:是带盘符的
相对路径:是不带盘符的,默认到当前项目下去找
创建File对象的目的是:
为了调用里面的方法
1.2 File常见的成员方法
1.2.1 判断获取
方法名称 | 说明 |
---|---|
public boolean isDirectory() | 判断此路径名表示的File是否为文件夹 |
public boolean isFile() | 判断此路径名表示的File是否为文件 |
public boolean exists() | 判断此路径名表示的File是否存在 |
public long length() | 返回文件的大小(字节数量) |
public string getAbsolutePath() | 返回文件的绝对路径 |
public String getPath() | 返回定义文件时使用的路径 |
public String getName() | 返回文件的名称,带后缀 |
public long lastModified() | 返回文件的最后修改时间 (时间毫秒值) |
注意事项:
length
:只能获取到文件的大小,其单位是字节,不是字节就/1024进行转化,不能测量文件夹的大小,,若要测量文件夹的大小,就要把文件夹当中的文件大小全部累加起来getName:
如果是文件就是表示的为文件名+后缀名(aaa(文件名).java(后缀名)),文件夹只有
文件名
package File;
import java.io.File;
import java.text.SimpleDateFormat;
public class Dom2 {
public static void main(String[] args) {
//判断是否为文件夹,判断是否为文件,判断是否存在这个文件
File file1 = new File("D:\\deom\\deoms");
System.out.println(file1.isDirectory());//true,是文件夹
System.out.println(file1.isFile());//false ,不是文件
System.out.println(file1.exists());//true , 该路径存在File
//来算出其文件大小
File file2 = new File("D:\\deom\\deoms\\1 项目(总).html");
long len = file2.length();
System.out.println(len);//886
//获取到其相对路径名称
System.out.println(file2.getAbsoluteFile());//D:\deom\deoms\1 项目(总).html
//获取其文件名字
System.out.println(file2.getName());//1 项目(总).html
System.out.println(file1.getName());//deoms
//获取到该文件最后修改的时间
long time = file2.lastModified();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String format = simpleDateFormat.format(time);
System.out.println(time);//毫秒值:1674616961505
System.out.println(format);//2023年01月25日 11:22:41
}
}
1.2.2 创建删除
方法名称 | 说明 |
---|---|
public boolean createNewFile() | 创建一个新的空的文件 |
public boolean mkdir() | 创建单级文件夹 |
public boolean mkdirs() | 创建多级文件夹 |
public boolean delete() | 删除文件、空文件夹 |
注意事项
delete方法默认只能删除文件和空文件夹,delete方法直接删除不走回收站
,delete遇到文件直接删除,若是文件夹有内容不能删除,没内容可以直接删除createNewFile()
:1. 如果存在该文件,就返回false,不存在就返回true,并创建文件。2. 如果路径错误就会报错IOExceptionmkdir()
: 只能创建单级文件夹,在Windows当中文件的路径是唯一的,如果相同就不能创建文件夹mkdirs
:可以创建多级文件夹,也可以创建单级文件夹
package File;
import java.io.File;
import java.io.IOException;
public class Dom3 {
public static void main(String[] args) throws IOException {
// 创建一个新的空的文件
File file1 = new File("D:\\deom\\deoms\\aaa.html");
file1.createNewFile();
//创建单级文件夹
File file2 = new File("D:\\deom\\deoms\\bbb");
file2.mkdir();
//创建多级文件夹
File file3 = new File("D:\\deom\\deoms\\ccc\\aaa\\bbb");
file3.mkdirs();
//删除
file1.delete();
file2.delete();
}
}
1.2.3 获取遍历
方法名称 | 说明 |
---|---|
public File[] listFiles() | 获取当前该路径下所有内容 |
重点:
- 当调用者File表示的路径不存在时,返回null
- 当调用者File表示的路径是文件时,返回null
当调用者File表示的路径是一个空文件夹时,返回一个长度为0的数组
当调用者File表示的路径是一个有内容的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回
当调用者File表示的路径是一个有隐藏文件的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文
- 当调用者File表示的路径是需要权限才能访问的文件夹时,返回null
package File;
import java.io.File;
public class Dom4 {
public static void main(String[] args) {
File file1 = new File("D:\\deom\\deoms");
File[] files = file1.listFiles();
for (File file : files) {
System.out.println(file);
/*D:\deom\deoms\项目(放大镜).html
D:\deom\deoms\项目(清单).html
D:\deom\deoms\项目(购物车).html
D:\deom\deoms\项目(钟表).html*/
}
}
}
二、IO流
用于读写文件中的数据(可以读写文件,或网络中的数据...)
分类:
字节流
: 可以操作所有类型的文件
字符流
:只能操作纯文本文件
纯文本文件:就是用记事本打开的文件,可以读得懂的文件
2.1 IO流体系
2.2 FileOutputStream
操作本地文件的字节输出流,可以把程序中的数据写到本地文件中。
FileOutputStream的作用
可以把程序中的数据写到本地文件上,是字节流的基本流。
书写步骤:
- 创建字节,输出流对象
细节1
:参数是字符串表示的路径或者File对象都是可以的
细节2
:如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的
细节3
:如果文件已经存在,则会清空文件- 写数据
细节
: write方法的参数是整数,但是实际上写到本地文件中的是整数在ASCI上对应的字符- 释放资源
细节
:每次使用完流之后都要释放资源
package IOStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreams {
public static void main(String[] args) throws IOException {
//创建对象
FileOutputStream fos = new FileOutputStream(所需要写的代码路径);
fos.write(123);
fos.close();
}
}
原理:
- 通过第一行代码来创建程序与文件当中的传输
- 通过第二行,拿着需要写的内容,通过第一行创建的通道,八所要写的内容进行传输
- 最后将通道断裂
2.2.1 FileOutputStream写数据的3种方式
方法名称 | 说明 |
---|---|
void write(int b) | 一次写一个字节数据 |
void write(byte[] b) | 一次写一个字节数组数据 |
void write(byte[] b,int off, int len) | 一次写一个字节数组的部分数据 |
package IOStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Dom1 {
public static void main(String[] args) throws IOException {
byte[] arr = {97,98,99,100};
//创建对象
FileOutputStream fos = new FileOutputStream("代码路径");
//写数据
fos.write(arr);
//清除
fos.close();
}
}
2.2.2 FileOutputStream换行写:
再次写出一个换行符就可以了
windows: \r\n
Linux:\n
Mac:\r
细节:
- 在windows操作系统当中,java对回车换行进行了优化虽然完整的是\r\n,但是我们写其中一个\r或者\n,java也可以实现换行,因为java在底层会补全
- 建议;
不要省略,还是写全了。
2.2.3 FileOutputStream续写
- 如果想要续写,打开续写开关即可开关位置:创建对象的第二个参数默认false:
- 表示关闭续写,此时创建对象会清空文件手动传递true:表示打开续写,此时创建对象不会清空文件
package IOStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Dom2 {
public static void main(String[] args) throws IOException {
//创建对象
FileOutputStream fos = new FileOutputStream("代码的路径",true);
//写数据
String str1 = "kankelaoyezuiniubi";
byte[] bytes1 = str1.getBytes();
fos.write(bytes1);
//换行
String str2 = "\r\n";
byte[] bytes2 = str2.getBytes();
fos.write(bytes2);
//添加数据
String str3 = "huangleiniuniuniu";
byte[] bytes3 = str3.getBytes();
fos.write(bytes3);
//清除
fos.close();
}
}
2.3 FilelnputStream
操作本地文件的字节输入流,可以把本地文件中的数据读取到程序中来
书写步骤:
- 创建字节,输出流对象
细节1
:如果文件不存在,就直接报错- 写数据
细节1
: 一次读一个字节,读出来的是数据在ASCII上对应的数字
细节2
:读到文件末尾了,read方法返回-1。
- 释放资源
细节
:每次使用完流之后都要释放资源
package IOStream.FilelnputStreams;
import java.io.FileInputStream;
import java.io.IOException;
public class Dom1 {
public static void main(String[] args) throws IOException {
//创建对象
FileInputStream fls = new FileInputStream("E:\\Java文件夹\\代码\\basicDom\\代码\\test\\text5\\src\\IOStream\\123.txt");
//循环添加
int b = 0;
while ((b = fls.read())!= -1){
System.out.print((char) b);
}
//清除
fls.close();
}
}
注意:
必须得用第三变量来赋值,如果不用第三变量赋值,用fls.read(),就会导致每次调用都会使得指针向后移动一位,导致出现的结果不正确
拷贝文件
package IOStream.FilelnputStreams;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class copyFile {
public static void main(String[] args) throws IOException {
//创建输入、输出对象
FileInputStream fis = new FileInputStream("拷贝的东西");
FileOutputStream fos = new FileOutputStream("需要拷贝的位置即名字");
//一边读一遍写
int b = 0;
while ((b = fis.read())!=-1){
fos.write(b);
}
//关闭,去除,先开后关
fos.close();
fis.close();
}
}
以上代码的弊端:
数据传输的太慢,每次传输的速度为1字节
拷贝升级版(一次读取多个字节)
方法名称 | 说明 |
---|---|
public int read() | 一次读一个字节数据 |
public int read(byte[] buffer) | 一次读一个字节数组数据 |
注意:一次读一个数组长度的数据,每次读取会尽可能把数组装满
原理:
package IOStream.FilelnputStreams;
import java.io.FileInputStream;
import java.io.IOException;
public class Dom2 {
public static void main(String[] args) throws IOException {
//创建读取对象
FileInputStream fis = new FileInputStream("E:\\Java文件夹\\代码\\basicDom" +
"\\代码\\test\\text5\\src\\IOStream\\123.txt");
//创建数组长度为2
byte[] bytes = new byte[2];
int len;
len = fis.read(bytes);
//打印一下当前bytes读取到的数据
System.out.println(new String(bytes,0,len));//ab
int len2;
len2 = fis.read(bytes);
//打印一下当前bytes读取到的数据
System.out.println(new String(bytes,0,len2));//cd
//释放资源
fis.close();
}
}
升级版:
package IOStream.FilelnputStreams;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class copyFilePlus {
public static void main(String[] args) throws IOException {
//创建输入、输出对象
FileInputStream fis = new FileInputStream("C:\\Program Files (x86)\\Lenovo\\LegionZone\\1.0.5.7282\\localhtml\\static\\media\\guide.7193e7d.mp4");
FileOutputStream fos = new FileOutputStream("E:\\Java文件夹\\代码\\basicDom\\代码\\test\\text5\\src\\IOStream\\copy.mp4");
//定义一个数组来进行拷贝数据
byte[] bytes = new byte[1024*1024*2];
int len;
len=fis.read(bytes);
while (len != -1){
fos.write(bytes,0,len);
}
//关闭,去除,先开后关
fos.close();
fis.close();
}
}
2.4 异常处理细节版
try……catch……finally……
特点: finally里面的代码一定被执行,除非虚拟机停止
我们常用 接口: AutoCloseable释放资源
特点:特定的情况下,可以自动释放资源
2.5 字符集
2.5.1 计算机的存储规则(英文)
2.5.2 计算机的存储规则 GBK—>(英文)
2.5.3 计算机的存储规则 GBK—>(汉字)
规则1:汉字两个字节存储
规则2:高位字节二进制一定以1开头,转成十进制之后是一个负数
2.5.4 计算机的存储规则(英文)(Unicode )
UTF-16编码规则: 用2~4个字节保存
UTF-32编码规则:固定使用四个字节保存
UTF-8编码规则:用1~4个字节保存
ASCII 1个字节
简体中文 3个字节
2.5.5 计算机的存储规则(中文)(Unicode )
Unicode字符集的UTF-8编码格式
- 一个英文占一个字节,二进制第一位是0,转成十进制是正数
- 一个中文占三个字节,二进制第一位是1,第一个字节转成十进制是负数
为什么会出现乱码
- 用字节流来读取数据
导致的是一个字节,一个字节的传输,在解码中文时就会出错
- 解码与编码不相符合
比如UTF-8 和GBK , UTF-8中文是用三个字节,而GBK是用两个字节,所以会出错
解决方法
- 不要用字节流读取文本文件
- 编码解码时使用同一个码表,同一个编码方式,
Java中编码的方法
string类中的方法 | 说明 |
---|---|
public byte[] getBytes() | 使用默认方式进行编码 |
public byte[] getBytes(string charsetName) | 使用指定方式进行编码 |
Java中解码的方法
string类中的方法 | 说明 |
---|---|
String(byte [] bytes) | 使用默认方式进行解码 |
String(byte[] bytes, String charsetName) | 使用指定方式进行解码 |
package IOStream.StringStream;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class 解码编码 {
public static void main(String[] args) throws UnsupportedEncodingException {
//编码(空参-->UTF-8 “传输的编写规则”-->对应的编码规则)
String str = "ai你哈哈哈";
byte[] bytes1 = str.getBytes();
System.out.println(Arrays.toString(bytes1));//[97, 105, -28, -67, -96, -27, -109, -120, -27, -109, -120, -27, -109, -120]
byte[] bytes2 = str.getBytes("GBK");
System.out.println(Arrays.toString(bytes2));//[97, 105, -60, -29, -71, -2, -71, -2, -71, -2]
//解码
String by1 = new String(bytes1);
System.out.println(by1);//ai你哈哈哈
String by2 = new String(bytes2, "GBK");
System.out.println(by2);//ai你哈哈哈
String by3 = new String(bytes2);
System.out.println(by3);//ai�������,乱码
}
}
2.6 字符流
字符流的底层其实就是字节流
特点:
输入流:一次读一个字节,遇到中文时,一次读多个字节
输出流:底层会把数据按照指定的编码方式进行编码,变成字节再写到文件中
2.6.1 FileReader
- 创建字符输入流对象
构造方法 | 说明 |
---|---|
public FileReader(File file) | 创建字符输入流关联本地文件 |
public FileReader(string pathname | 创建字符输入流关联本地文件 |
细节1:如果文件不存在,就直接报错
- 读取数据
成员方法 | 说明 |
---|---|
public int read() | 读取数据,读到末尾返回-1 |
public int read(charr7 buffer) | 读取多个数据,读到末尾返回-1 |
细节1:按字节进行读取,遇到中文,一次读多个字节,读取后解码,返回一个整数
细节2:读到文件末尾了,read方法返回-1。
- 资源
空参代码展示:
package FileReaders;
import java.io.FileReader;
import java.io.IOException;
public class Dom1 {
public static void main(String[] args) throws IOException {
//创建对象
FileReader reader = new FileReader("E:\\Java文件夹\\代码\\basicDom\\" +
"代码\\test\\text5\\src\\IOStream\\123.txt");
//读取对象
int read ;
while ((read = reader.read()) != -1){
System.out.print((char) read);
}
//资源回收
reader.close();
}
}
read ()细节:
- read():默认也是一个字节一个字节的读取的,如果遇到中文就会一次读取多个
- 在读取之后,方法的底层还会进行解码并转成十进制。
最终把这个十进制作为返回值
这个十进制的数据也表示在字符集上的数字
英文
: 文件里面二进制数据 0110 0001
read方法进行读取,解码并转成十进制97中文
:
文件里面的二进制数据 11100110 10110001 10001001
read方法进行谈取,解码并转成十进制27721
我想看到中文汉字,就是把这些十进制数据,再进行强转就可以了
read(chars)细节:
- 读取数据,解码,强转三步合并了,把强转之后的字符放到数组
- 可以当作空参read + 强转类型转换
有参代码展示:
package FileReaders;
import java.io.FileReader;
import java.io.IOException;
public class Dom2 {
//有参代码实现
public static void main(String[] args) throws IOException {
//创建对象
FileReader fr = new FileReader("E:\\Java文件夹\\代码\\" +
"basicDom\\代码\\test\\text5\\src\\IOStream\\123.txt");
//创建个数组接收
char[] ch = new char[2];
int len;
while ((len = fr.read(ch)) != -1){
System.out.print(ch);
}
//清理资源
fr.close();
}
}