File,是用来操作系统的文件的。
IO流是用来读写数据的
File创建对象,File对象既可以代表文件,也可以代表文件夹
public static void main(String[] args) {
//第一种分隔符
File file = new File("D:\\a.txt");
long length = file.length();
//第二种分隔符
File file1 = new File("D:/a.txt");
//第三种分隔符 用File.separator 代替所有的分隔符
File file2 = new File("D" + File.separator + "a.txt");
//File也可以指向一个不存在的文件
File file3 = new File("D:\\aaa.txt");
boolean exists = file3.exists(); //判断是否存在
//如何定位模块中的文件 这是他的绝对路径
File file4 = new File("D:\\Java\\java-01\\java01\\src\\main\\java\\lian02\\b.txt");
System.out.println(file4.length());
//最终要的是相对路径
File file5 = new File("java01\\src\\main\\java\\lian02\\b.txt");
System.out.println(file5.length());
}
如何找到文件的绝对路径,右击b.txt文件,选中Copy Paht/Refernece ,选中绝对路径即可。
最重要的是相对路径,如何写相对路径
绝对路径,去掉模块前面的路径就是相对路径。
File提供的判断文件类型、获取文件信息功能
public static void main(String[] args) {
//判断当前文件对应的文件路径是否存在
File file = new File("D:\\a.txt");
boolean exists = file.exists();
//判断当前文件是否指向文件
File file1 = new File("D:\\a.txt");
boolean file2 = file1.isFile();
//判断当前文件是否是文件夹
boolean directory = file1.isDirectory();
//获取文件名称
String name = file.getName();
//获取文件大小
long length = file.length();
//获取文件最后修改时间
long time = file.lastModified(); //获取的是毫米值
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format = sdf.format(time);
System.out.println(format);
//获取文件创建时获取的路径
File file3 = new File("D:\\a.txt");
File file4 = new File("java01\\src\\main\\java\\lian02\\b.txt");
String path = file3.getPath();
String path1 = file4.getPath();
//获取绝对路径
String absolutePath = file3.getAbsolutePath();
}
掌握File文件创建和删除文件相关方法
public static void main(String[] args) throws IOException {
//public boolean creatNewFile() 创建新的文件,内容为空
File file = new File("D:\\b.txt");
boolean newFile = file.createNewFile();
//public boolean mkdir() 只能创建一级文件夹
File file1 = new File("D:\\a");
boolean mkdir = file1.mkdir();
//public boolean mkdirs() 创建多级文件夹
File file2 = new File("D:\\b\\c");
boolean mkdirs = file2.mkdirs();
//删除文件或空文件夹,不能删除非空文件夹
//public boolean delete()
boolean delete = file1.delete();
boolean delete1 = file.delete();
}
File类提供遍历文件夹
public static void main(String[] args) throws IOException {
//public String[] list()
// 获取当前目录下所有的一级文件名称到一个字符串数组中返回
File file = new File("D:\\"); //获取D盘下所有的文件和文件夹名称
String[] names = file.list();
for (String name : names) {
System.out.println(name);
}
//public File[] listFiles[]
//获取当前目录下所有的一级文件对象到一个文件对象数组中去(重点)
File[] files = file.listFiles();
for (File file1 : files) {
String absolutePath = file1.getAbsolutePath();
}
}
方法递归,计算n的阶乘
递归算法三要素:
递归的公式:f(n) = f(n-1)*n; 递归的终结点:f(1); 递归的方向必须走向终结点。
public static void main(String[] args) throws IOException {
System.out.println(f(5));
}
public static int f(int n){
//终结点
if (n == 1){
return 1;
}else{
return f(n - 1)*n;
}
}
猴子吃桃问题,每天吃原来桃子的一半,再多吃一个。
public static void main(String[] args) throws IOException {
//猴子吃桃问题,每天吃原来的一半,再多吃一个。第10天剩下一个
// f(x)-f(x)/2-1=f(x+1)
//f(x)=2f(x+1)+2
System.out.println(f(1));
}
public static int f(int n){
//终结点
if (n == 10){
return 1;
}else{
return 2*f(n + 1)+2;
}
}
文件搜索 (重要)
public static void main(String[] args) {
searchFile(new File("D:\\"),"a.txt");
}
//搜索文件
public static void searchFile(File file,String fileName){
//先判断输入的file是不是合法的
//file是不是空,是不是目录,路径正不正确
if (file == null || file.isFile() || !file.exists()){
return;
}
File[] files = file.listFiles();
if (files !=null && files.length >0){
for (File file1 : files) {
if (file1.isFile()){
if (file1.getName().equals(fileName)){
System.out.println(file.getAbsolutePath());
}
}else {
searchFile(file1,fileName);
}
}
}
}
删除所有文件(重要)
public static void main(String[] args) {
deleteFile(new File("D:\\新建文件夹"));
}
//删除文件夹或文件
public static void deleteFile(File file){
//如果获取不到访问权限,或者文件地址不存在
if (file == null || !file.exists()){
return;
}
//如果是文件直接删除
if (file.isFile()){
file.delete();
return;
}
//如果是文件夹(先拿到一级文件夹一级对象,判断是否为空)
File[] files = file.listFiles();
//如果没有访问权限,直接返回
if (files == null){
return;
}
//如果是空文件夹直接删除
if (files.length == 0){
file.delete();
}
//如果文件有内容,遍历一级对象
for (File file1 : files) {
if (file1.isFile()){
file1.delete();
}else{
deleteFile(file1);
}
}
file.delete();// 删除本身,所以判断文件夹为空的代码,可以删除,最后要删除本身
}
啤酒问题:啤酒2元一瓶,2个瓶子换一瓶,4个盖子换一瓶。10元可以喝几瓶
public static int allNumber;
public static int lastBattleNumber;
public static int lastCoverNumber;
public static void main(String[] args) {
buy(10);
System.out.println(allNumber);
System.out.println(lastBattleNumber);
System.out.println(lastCoverNumber);
}
public static void buy(int money){
//先买再说
int buyNumber = money / 2;
allNumber += buyNumber;
//计算本轮总的瓶子数和瓶盖数
int allBattleNumber = buyNumber + lastBattleNumber;
int allCoverNumber = buyNumber + lastCoverNumber;
//计算瓶子数和瓶盖数换算成钱
//如果说瓶子数大于等于2可以继续换钱
int allMoney=0;
if (allBattleNumber >= 2){
allMoney = (allBattleNumber / 2 )*2;
}
lastBattleNumber = allBattleNumber % 2;
if (allCoverNumber >=4){
allMoney += (allCoverNumber / 4)*2;
}
lastCoverNumber = allCoverNumber % 4;
//判断allMoney是否大于2,大于2继续买
if (allMoney >=2){
buy(allMoney);
}
}
字符集
编码:把字符按着指定字符集编码成字节。
解码:把字节按着指定字符集解码成字符。
编码字符串提供的方法
解码通过构造器
//编码
String data = "a我b";
byte[] bytes = data.getBytes(); //按着系统默认编码
System.out.println(Arrays.toString(bytes));
//自定义方式编码
byte[] bytes1 = data.getBytes("GBK");
System.out.println(Arrays.toString(bytes1));
//---------------------------------------------------
//解码 通过new String() 方式
String s = new String(bytes);
System.out.println(s);
String gbk = new String(bytes1, "GBK");
System.out.println(gbk);
IO流概述
//1.创建文件字节输入流管道,与源文件接通
InputStream fileInputStream = new FileInputStream(new File("java01\\src\\main\\java\\lian02\\b.txt"));
//第二种写法,直接写路径更加简化
InputStream fileInputStream1 = new FileInputStream("java01\\src\\main\\java\\lian02\\b.txt");
//2.开始读取字节数据,读取一个字节,如果没有字节了,返回-1
//public int read();
int read1 = fileInputStream.read();
System.out.println(read1);
public static void main(String[] args) throws IOException {
//1.创建文件字节输入流管道,与源文件接通
InputStream fileInputStream = new FileInputStream(new File("java01\\src\\main\\java\\lian02\\b.txt"));
//第二种写法,直接写路径更加简化
InputStream fileInputStream1 = new FileInputStream("java01\\src\\main\\java\\lian02\\b.txt");
//2.开始读取字节数据,读取一个字节,如果没有字节了,返回-1
//public int read();
int read1 = fileInputStream.read();
System.out.println(read1);
//使用循环改造代码
int b; //用于记住读取的字节
while((b = fileInputStream.read()) !=-1){
System.out.println(b);
}
//一个一个读取性能差
//读取汉字肯定会乱码,无法避免
//流使用完毕,必须关闭,释放系统资源
fileInputStream.close();
fileInputStream1.close();
}
一次读取一数组字节
public static void main(String[] args) throws IOException {
InputStream is = new FileInputStream("java01\\src\\main\\java\\lian02\\b.txt");
//b.txt一共就5个数据 afa34
//开始读取文件的字节数据
byte[] buffer=new byte[3];
int read = is.read(buffer);
String s = new String(buffer);
System.out.println(s); //读取为 afa
//再读取一次
// int read1 = is.read(buffer);
// String s1 = new String(buffer);
// System.out.println(s1); //读取为 34a
//读取多少倒多少
int read2 = is.read(buffer);
String s2 = new String(buffer, 0, read2);
System.out.println(s2);
//如果没有数据,读取结果为-1
int read3 = is.read(buffer);
String s3 = new String(buffer);
System.out.println(s3); //为-1
}
简化上述代码
public static void main(String[] args) throws IOException {
InputStream is = new FileInputStream("java01\\src\\main\\java\\lian02\\b.txt");
byte[] bytes=new byte[3];
int len; //记住每次读取了多少个字节
while ((len =is.read(bytes)) != -1){
String s = new String(bytes,0,len); //读取多少,倒出多少
System.out.println(s);
}
is.close();//关闭流
//每次读取多个字节,性能提升
//还是不能解决中文乱码问题
}
文件字节输入流,一次读取全部文件
//一次性读取文件全部字节到一个字节数组中去
//创建一个字节输入流管道与源文件接通
InputStream is = new FileInputStream("java01\\src\\main\\java\\lian02\\b.txt");
//准备一个字节数组,大小正好和文件大小一样
File file = new File("java01\\src\\main\\java\\lian02\\b.txt");
long length = file.length();
byte[] bytes=new byte[(int) length];
int read = is.read(bytes);
String s = new String(bytes);
System.out.println(s);
再简化readAllBytes方法
public static void main(String[] args) throws IOException {
//一次性读取文件全部字节到一个字节数组中去
//创建一个字节输入流管道与源文件接通
InputStream is = new FileInputStream("java01\\src\\main\\java\\lian02\\b.txt");
byte[] bytes = is.readAllBytes();
System.out.println(new String(bytes)); //再去解码
}
文件字节输出流
//创建一个字节输出流管道,与目标文件接通
//第二个参数,如果是true,表示追加写数据
//第二个参数如果默认不写,表示覆盖原来数据
OutputStream os = new FileOutputStream("java01\\src\\main\\java\\lian02\\a.txt",true);
//开始写字节数据 一次只能写一个字节,写中文会乱码
os.write(97);
os.write('b');
//一次写一个数组
byte[] bytes = "我爱你中国www".getBytes();
os.write(bytes);
//一次写一个数组的指定字节
os.write(bytes,0,15);
// \r\n是换行符, \n只能兼容windows平台, \r\n兼容所有平台
os.write("\r\n".getBytes());
os.close();
案例-文件复制(这个代码非常重要可以做一切文件的复制,包括文本、图片、视频)
public static void main(String[] args) throws IOException {
//复制文件
InputStream is = new FileInputStream("D:\\迅雷\\无标题.png");
OutputStream os = new FileOutputStream("D:\\无标题.png");
//创建一个字节数组,负责转移数据
byte[] bytes = new byte[1024];
int len; //记住每次读取了多少个字节
while ((len = is.read(bytes)) !=-1){
os.write(bytes,0,len); //从输入流读取多少个字节,就输出多少个字节
}
os.close();
is.close();
}
字节流适合做一切文件的复制操作。
流释放存在问题,一旦中间的代码出现问题,流就不能释放。
除了代码中有System.exit(0) ,否则finally中的代码一定会执行
try{
System.out.println(10 / 0);
return;
//System.exit(0);退出虚拟机,除了这个代码,finally中的代码一定会执行
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println("finally一定执行");
}
finally中,不要return语句,否则会影响。
public static void main(String[] args) throws IOException {
System.out.println(chu(2, 1));
}
public static int chu(int a,int b){
try {
return a / b;
}catch (Exception e){
e.printStackTrace();
return -1;
}finally {
return 0;
}
}
finally一般用于在程序执行完之后进行资源的释放操作。
把复制文件代码用try-catch-finally 代码包围后会报错
因为is和os的定义只在try代码中有效。把InputStream 和OutputStream定义提到try代码外
但是os.close()和is.close() 又会爆红 ,因为finally中的代码一定会执行,如果代码在 InputStream和OutputStream代码定义之前就报错了,就会导致空指针异常。
先对os和is判断对象是否为null,然后再try-catch就可以解决。完整代码如下
public static void main(String[] args) {
InputStream is=null;
OutputStream os=null;
try {
is = new FileInputStream("java01\\src\\main\\java\\lian02\\b.txt");
os = new FileOutputStream("java01\\src\\main\\java\\lian02\\m.txt");
//创建一个字节数组负责转移数据
byte[] bytes=new byte[1024];
int len;//记住每次读取了多少个字节
while ((len =is.read(bytes)) != -1){
os.write(bytes);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (os !=null )os.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (is !=null )is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
上述代码虽然规范,但是太臃肿
//try()的括号里,只能放置资源对象(流对象) //什么是资源呢?资源都会实现AutoCloseable接口。资源都有一个close()方法 //资源被用完之后,都会自动调用close方法完成资源的释放
public static void main(String[] args) {
try ( InputStream is = new FileInputStream("D:\\dog.png");
OutputStream os = new FileOutputStream("D:\\dogg.png");
//try()的括号里,只能放置资源对象(流对象)
//什么是资源呢?资源都会实现AutoCloseable接口。资源都有一个close()方法
//资源被用完之后,都会自动调用close方法完成资源的释放
){
byte[] bytes = new byte[1024];
int len;
while ((len = is.read(bytes)) != -1) {
os.write(bytes);
}
} catch (IOException e) {
e.printStackTrace();
}
}