Java File与IO流学习笔记

内存中存放的都是临时数据,但是在断电或者程序终止时都会丢失

而硬盘则可以长久存储数据,即使断电,程序终止,也不会丢失

File

  • Filejava.io.包下的类,File类的对象,用于代表当前操作系统的文件(可以是文件,或文件夹)
  • 可以获取文件信息(大小,文件名,修改时间)
  • 判断文件的类型
  • 创建文件或者文件夹
  • 删除文件或者文件夹…
  • 但是File类只能对文件本身进行操作,不能读写文件里面存储的数据
创建File对象
构造器说明
public File(String pathname)根据文件路径创建文件对象
public File(String parent,String child)根据父路径和子路径名字创建文件对象
public File(File parent,String child)根据父路径对应文件对象和子路径名字创建文件对象

案例

Main.java

import java.io.File;public class Main {public static void main(String[] args) {// 创建一个File对象,指代某个具体的文件File file = new File("C:\\Users\\huihui\\Desktop\\test.txt");System.out.println(file); // C:\Users\huihui\Desktop\test.txtSystem.out.println(file.length()); // 文件大小 0File file1 = new File("C:/Users/huihui/Desktop/test.txt");System.out.println(file1); // C:\Users\huihui\Desktop\test.txtFile file2 = new File("C:" + File.separator +"Users"+ File.separator + "huihui"+ File.separator + "Desktop"+ File.separator + "test.txt");System.out.println(file2); // C:\Users\huihui\Desktop\test.txt}
}

注意:File对象也可以指代一个不存在的文件路径

Main.java

import java.io.File;public class Main {public static void main(String[] args) {File file = new File("aa/bb/cc");System.out.println(file.length()); // 0// 可以通过exists()方法判断文件是否存在System.out.println(file.exists()); // false}
}
路径
  • 路径分为绝对路径(带盘符)和相对路径(不带盘符)
import java.io.File;public class Main {public static void main(String[] args) {// 据对路径,带盘符(是种写死的路径)File file = new File("D:\\Idea\\Codeing\\Day01\\src\\Demo\\Student.java");System.out.println(file); // D:\Idea\Codeing\Day01\src\Demo\Student.java// 相对路径,不带盘符(是种灵活的路径),默认回去当前工程下寻找文件File file1 = new File("src\\Demo\\Student.java");System.out.println(file1); // src\Demo\Student.java}
}
方法
判断文件类型,获取文件信息

在这里插入图片描述

案例

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.logging.SimpleFormatter;public class Main {public static void main(String[] args) {File file = new File("C:\\Users\\huihui\\Desktop\\test.txt");// 1. exists() 文件是否存在System.out.println(file.exists()); // true// 2. isFile() 判断是否是文件System.out.println(file.isFile()); // true// 3. isDirectory() 判断是否是文件夹System.out.println(file.isDirectory()); // false// 4. getName() 获取文件的名称包括后缀System.out.println(file.getName()); // test.txt// 5. length() 获取文件大小,返回字节个数System.out.println(file.length()); // 0// 6. laseModified() 获取文件的最后修改时间,默认返回的是时间戳// System.out.println(file.lastModified()); // 1696232257337SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(file.lastModified())); // 2023-10-02 15:37:37// 7. getPath() 获取创建文件对象时,使用的路径(你写的是什么路径,它就会返回什么路径)System.out.println(file.getPath()); // C:\Users\huihui\Desktop\test.txt// 8. getAbsolutePath() 获取绝对路径System.out.println(file.getAbsolutePath()); // C:\Users\huihui\Desktop\test.txt}
}
创建或者删除文件

在这里插入图片描述

案例

import java.io.File;
import java.io.IOException;public class Main {public static void main(String[] args) throws IOException {// 1. createNewFile() 创建一个新的文件,但是需要抛出异常。返回一个布尔值,如果存在,再创建就会返回falseFile file = new File("D:\\Idea\\Codeing\\Day01\\src\\Demo\\test.txt");System.out.println(file.createNewFile()); // true// 2. mkdir() 用于创建文件夹,但是只能创建一级文件夹。返回一个布尔值File f2 = new File("D:\\Idea\\Codeing\\Day01\\src\\Demo01");System.out.println(f2.mkdir()); // true// 3. mkdirs() 用于创建文件夹,可以创建多级文件夹File f3 = new File("D:/Idea/Codeing/Day01/src/Demo02/aa/bb");System.out.println(f3.mkdirs()); // true// 4. delete() 删除文件或者空文件,但是不能删除非空文件夹}
}
遍历文件夹

File类提供的遍历文件夹的功能

方法说明
public String[] list()获取当前目录下所有的“一级文件名称”,返回一个字符串数组
public File[] listFiles()获取当前目录下所有的“一级文件对象”,返回一个文件对象数组

使用listFiles注意事项:

  • 当主调是文件,或者路径不存在时,返回null
  • 当主调是空文件夹时,返回一个长度为0的数组
  • 当主调是一个有内容的文件夹时,将里面所有一级文件和文件夹的路径放在File数组中返回
  • 当主调是一个文件夹,且里面有隐藏文件时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件
  • 当主调是一个文件夹,但是没有权限访问改文件夹时,返回null
import java.io.File;
import java.util.Arrays;public class Main {public static void main(String[] args) {File file = new File("D:\\Idea\\Codeing\\Day01\\src\\Demo");// 1. public String[] list(): 获取当前目录下所有的 "一级文件名称"String[] list = file.list();System.out.println(Arrays.toString(list)); // [Student.java, test.txt]// 2. public File[] listFiles(): 获取当前目录下所有的 "一级文件对象"File[] files = file.listFiles();for (File file1 : files) {System.out.println(file1.isFile()); // true trueSystem.out.println(file1.getAbsolutePath()); // }}
}
递归

案例1:修改文件序号

import java.io.File;public class Main {public static void main(String[] args) {// 改变某个文件夹下的文件的序号,要求从19开始File f = new File("C:\\Users\\huihui\\Desktop\\test");// 1. 得到里面所有的文件对象File[] files = f.listFiles();for (File file : files) {String name = file.getName();String start = name.substring(0, name.indexOf("."));String end = name.substring(name.indexOf("."));String newName = (Integer.valueOf(start) + 18) + end;// 开始改名file.renameTo(new File(f, newName));}}
}

递归就是方法调用自身,递归一定要有一个结束条件,不然会无限递归,造成栈内存溢出(因为方法会进入栈内,每次调用都会进栈,但是一直没有出来的话,栈内存中的方法就会越来越多,就会溢出)

递归形式:

  1. 直接递归:方法自己调用自己
  2. 间接递归:方法调用其他方法,其他方法又回调方法自己

直接递归:

public class Main {public static void main(String[] args) {print(0);}// 直接递归:方法内部直接调用自己public static void print(int num) {if(num < 10) {System.out.println("打印输出");print(++num);}}
}

间接递归:

public class Main {public static void main(String[] args) {print(0);}public static void print(int num) {temp(num);}// 间接递归:别的方法调用自己public static void temp(int num) {if(num < 10) {System.out.println("打印输出");print(++num);}}
}
求阶乘
public class Main {public static void main(String[] args) {System.out.println(print(5)); // 120}// 计算结阶乘public static int print(int num) {if(num == 1) return 1;return print((num - 1)) * num;}
}

在这里插入图片描述

求1-n的和
public class Main {public static void main(String[] args) {System.out.println(sum(5)); // 15}// 计算1-n的和public static int sum(int num) {if(num == 1) return 1;return sum(num - 1) + num;}
}
猴子吃桃

猴子第一天摘下若干桃子,当即吃了一般,觉得好不过瘾,于是又多吃了一个。第二天又吃了前天剩余桃子数量的一般,觉得好不过瘾于是又多吃了一个。以后每天都是吃昨天剩余桃子数量的一半加一个。到第十天就只剩一个桃子了。问猴子摘了多少桃子?

f(x) - f(x)/2 - 1 = f(x + 1) // 昨天吃的减去前天的一半再减1,就是今天的

public class Main {public static void main(String[] args) {System.out.println(sum(1)); // 1534}// 计算1-n的和public static int sum(int num) {if(num == 10) return 1;return 2 * sum(num + 1) + 2;}
}
搜索文件

D:盘中,搜索QQScLauncher.exe这个文件,找到后直接输出位置并打开

import java.io.File;
import java.io.IOException;public class Main {public static void main(String[] args) throws IOException {String path = getPath(new File("D:\\QQ\\Bin"), "QQScLauncher.exe");System.out.println(path); // C:\Users\huihui\Desktop\Test\test.txt}// 在c盘中找到 test.txt 文件,并输出位置public static String getPath(File dir, String fileName) throws IOException {if(dir == null || !dir.exists() || dir.isFile()) return "您输入的路径有误";// 首先遍历一级文件File[] files = dir.listFiles();// 判断当前目录下是否存在一级文件对象,一级是否可以拿到一级文件对象if(files != null && files.length > 0) {// 找到里面的文件并对比for (File file : files) {if(file.isFile() && file.getName().contains(fileName)) {// 打开文件 运行时对象Runtime runtime = Runtime.getRuntime();runtime.exec(file.getAbsolutePath());return file.getAbsolutePath();} else {getPath(file, fileName);}}}return "没有搜索到";}
}
删除非空文件夹
import java.io.File;public class Main {public static void main(String[] args) {delFile(new File("C:/Users/huihui/Desktop/kong"));}// 删除非空文件夹public static void delFile(File file) {// 判空,不存在或者传的为空则不处理if(!file.exists() || file == null) return;// 如果是文件,则直接删除if(file.isFile()) {file.delete();return;}// 存在且是文件夹File[] files = file.listFiles(); // 拿到下面的一级文件对象if(files == null) return; // 如果文件夹为空(没有权限),则不处理// 有权限,不为空的文件夹,遍历进行删除里面的内容,并且最后要把自己空的文件夹删除for (File f : files) {if(f.isFile()) { // 是文件,直接删除f.delete();} else { // 文件夹,接着递归delFile(f);}}file.delete(); // 最后别忘了把自己空的文件夹删除}
}

字符集

在这里插入图片描述

UTF-8

重点:

  • ASCII字符集:只有英文,数字,符号等。占1个字节
  • GBK字符集:汉字占2个字节,英文,数字占1个字节
  • UTF-8字符集:汉字占3个字节,英文,数字占1个字节

字符编码时使用的字符集,喝解码时使用的字符集必须一致,否则就会出现乱码。

但是数字和英文一般都不会出现乱码,因为大部分字符集都要兼容ASCII

编码与解码

编码:把字符按照指定字符集编码成字节

解码:把字节按照指定字符集解码成字符

编码
方法名说明
byte[] getBayes()使用平台的默认字符集将改String编码为一系列字节,将结果存储到新的字节数组中
byte[] getBytes(String charsetName)使用指定的字符集将改String编码为一系列字节,将结果存储到新的字节数组中
import java.io.UnsupportedEncodingException;
import java.util.Arrays;public class Main {public static void main(String[] args) throws UnsupportedEncodingException {String str = "a的1";// 编码byte[] b1 = str.getBytes(); // 按照平台默认的字符编码规则编码System.out.println(Arrays.toString(b1)); // [97, -25, -102, -124, 49] 97:a 49:1 中间3个表示中文byte[] gbks = str.getBytes("GBK");System.out.println(Arrays.toString(gbks)); // [97, -75, -60, 49] gbk编码规则中中文是2个字节}
}
解码
方法名说明
String(byte[] bytes)通过使用平台的默认字符集解码,指定的字节数组,来构造新的String
String(byte[] bytes, String charsetName)通过指定的字符集解码,指定的租界数组,来构造新的String
import java.io.UnsupportedEncodingException;
import java.util.Arrays;public class Main {public static void main(String[] args) throws UnsupportedEncodingException {String str = "a的1";// 编码byte[] b1 = str.getBytes(); // 按照平台默认的字符编码规则编码System.out.println(Arrays.toString(b1)); // [97, -25, -102, -124, 49] 97:a 49:1 中间3个表示中文byte[] gbks = str.getBytes("GBK");System.out.println(Arrays.toString(gbks)); // [97, -75, -60, 49] gbk编码规则中中文是2个字节// 解码String s = new String(b1);System.out.println(s); // a的1String gbk = new String(gbks, "GBK");System.out.println(gbk); // a的1}
}

IO流

在这里插入图片描述

  • File代表文件。而IO流则可以读写数据

在这里插入图片描述

应用:

在这里插入图片描述

分类:
在这里插入图片描述

具体体系

在这里插入图片描述

输入输出都是以内存为基准的。程序在内存中运行,读写速度快,但是断电或者关闭就会清空数据。而硬盘(又叫磁盘)却可以永久存储数据,但是读写速度相对较慢。

输入:磁盘向内存中输入,也可以说内存读磁盘的数据

输出:内存向磁盘输出,也可以说内存向磁盘写入数据

内存和磁盘想要读写数据,就必须建立连接,而这个链接,就是流。类似与一个管道,只不过管道中流的是数据

数据又分为字节和字符,字节可以操作任意文件,而字符专注与操作各种文本文件(例如txt文件.java文件。。。)

输入流
  • 然后按照文件的最小单位,又可以分为 字节输入流字符输入流
字节输入流
  • InputStream抽象类表示,比较常用的实现类是FileInputStream

作用:

  • 以内存为基准,可以把磁盘文件中的数据以字节的ing是读入到内存中去(也就是读入带程序中去,因为程序放在内存中运行)

首先要创建管道,链接磁盘和内存

构造器说明
public FileInputStream(File file)创建字节输入流管道与源文件接通
public FileInputStream(String pathName)创建字节输入流管道与源文件接通

然后就可以Java提供的方法进行读写了

方法名说明
public int read()每次读取一个字节返回,如果发现没有数据可读会返回-1
public int read(byte[] buffer)每次用一个字节数组去读取数据,返回字节数组读取了多少个字节,如果返现没有数据可读就会返回-1

测试文件

a测试文件
读取一个字节
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;public class Main {public static void main(String[] args) throws IOException {// 首先创建管道链接InputStream fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");// 读数据,一次只读一个字节int read = fis.read();System.out.println((char) read); // a// 最后别忘关闭通道(关闭流)fis.close();}
}

对上面的改造优化

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;public class Main {public static void main(String[] args) throws IOException {// 首先创建管道链接InputStream fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");// 读数据,一次只读一个字节int num; // 记录读取的字符while ((num = fis.read()) != -1) { // 不等于-1说明还有字节System.out.print((char) num); // a测试文件}// 最后别忘关闭通道(关闭流)fis.close();}
}

但是这种有问题:读取汉字的时候会乱码(因为utf8中,汉字是3个字节,这一次只能读一个,肯定会乱码),并且读取性能不高

读取多个字节
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;public class Main {public static void main(String[] args) throws IOException {// 首先创建管道链接InputStream fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");// 读数据,可以自己设定一次读多少个字节byte[] bytes = new byte[3];// 第一次读取// read(byte[] buffer) 返回的是一次读取了多少个字节个数。如果最后一次读取,不到3个字节,那有几个字节,它就是几int len = fis.read(bytes);System.out.println(len); // 3// bytes 中存放的就是读取的3个字节 ['a','1','2']System.out.println(new String(bytes)); // a12// 第二次读取int len2 = fis.read(bytes);System.out.println(len2); // 2 因为最后的字节只有2个,不到3个,所以为2// bytes 中存放的就是读取的最新的3个字节 ['3','4','2'] 最后一个因为没有,所以还是用的原先的System.out.println(new String(bytes)); // 342// 但是显然上面的是不对的,正确的应该是 34 不应该有2System.out.println(new String(bytes, 0, len2)); // 34 第2个参数是开始位置,第3个参数是结束位置}
}

进行循环优化

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;public class Main {public static void main(String[] args) throws IOException {// 首先创建管道链接InputStream fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");// 读数据,可以自己设定一次读多少个字节byte[] bytes = new byte[3];// 当读取的长度不为我们设定的3时,就说明读取到到最后一个了int len; // 每次读取的字节长度while (((len = fis.read(bytes)) != -1)) {String s = new String(bytes, 0, len);System.out.println(s); // a12 34}// 关闭管道fis.close();}
}

但是这种一次读取多个字节,汉字依然是无法读取的。但是文件肯定是要有读取中文的现象,那我们改如何解决中文乱码的问题呢?

其实有一种办法,就是定义一个与文件一样大的字节数组,一次性读取文件的全部字节,这样不会出现中文乱码了

解决中文乱码的方法1

读取的文件:

a中文
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;public class Main {public static void main(String[] args) throws IOException {// 首先创建管道链接InputStream fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");// 获取文件大小File file = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");long length = file.length(); // 硬盘中的存储空间比较大,所以用的long类型// 读数据,可以自己设定一次读多少个字节byte[] bytes = new byte[(int)length]; // 内存里的存储空间比较小,所以用的int类型fis.read(bytes);System.out.println(new String(bytes)); // a中文fis.close();}
}

但是上面的方法,其实只能读取小的文件,超过int范围的文件一次性就读取不了了

解决中文乱码的方法2

Java官方为InputStrem提供了方法,可以直接把文件的全部字节读取到一个字节数组中返回

public byte[] readAllbytes() throw IOException // 直接将当前字节输入流对应的文件对象的字节数据撞到一个字节数组返回

那上面方法1就可以进行下面的简化

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;public class Main {public static void main(String[] args) throws IOException {// 首先创建管道链接InputStream fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");// 获取全部字节文件,并返回到一个新的字节数组byte[] bytes = fis.readAllBytes();String s = new String(bytes);System.out.println(s); // a中文fis.close();}
}
字符输入流
  • Reader抽象类表示,比较常用的实现类是FileReader

作用:

  • 以内存为基准,可以把文件中的数据以字符的形式读入到内存中去

首先要创建管道,链接磁盘和内存

构造器说明
public FileReader(File file)创建字符输入流管道与文件接通
public FileReader(String pathName)创建字符输入流管道与源文件接通

然后就是方法进行写入

方法名说明
public int read()每次读取一个字符返回,如果发现没有数据可读会返回-1
public int read(char[] buffer)每次用一个字符数组去读取数据,返回字符数组读取了多少个字符,如果发现没有数据可读会返回-1
读取一个字符
import java.io.FileReader;
import java.io.IOException;public class Main {public static void main(String[] args) throws IOException {// 首先创建一个字符链接管道FileReader fr = new FileReader("D:\\Idea\\Codeing\\Day01\\src\\test.txt");// 然后开始读,一次读取一个字符int read = fr.read();System.out.println((char) fr.read());fr.close();}
}

上面的可以进行优化

import java.io.FileReader;
import java.io.IOException;public class Main {public static void main(String[] args) throws IOException {// 首先创建一个字符链接管道FileReader fr = new FileReader("D:\\Idea\\Codeing\\Day01\\src\\test.txt");// 然后开始读,一次读取一个字符int num;while ((num = fr.read()) != -1) {System.out.println((char) num);}fr.close();}
}
读取多个字符
import java.io.FileReader;
import java.io.IOException;public class Main {public static void main(String[] args) throws IOException {// 首先创建一个字符链接管道FileReader fr = new FileReader("D:\\Idea\\Codeing\\Day01\\src\\test.txt");char[] chars = new char[3];// 读取多个字符int len; // 记住每次读取了多少个字符while ((len = fr.read(chars)) != -1) {System.out.print(new String(chars,0,len)); // 被复制的内容}fr.close();}
}
输出流
  • 然后按照文件的最小单位,又可以分为 字节输出流字符输出流
字节输出流
  • OutputStream抽象类表示,比较常用的实现类是FileOutputStream

作用:

  • 以内存为基准,把内存中的数据以字节的形式写出到文件中去

首先要创建管道,链接磁盘和内存

构造器说明
public FileOutputStream(File file)创建字节输出流管道与源文件接通
public FileOutputStream(String filePath)创建字节输出流管道与源文件接通
public FileOutputStream(File file,boolean append)创建字节输出流管道与源文件对象接通,可追加数据
public FileOutputStream(String filePath,boolean append)创建字节输出流管道与源文件对象接通,可追加数据

然后就可以Java提供的方法进行读写了

方法名说明
public void write(int a)写一个字节出去
public void write(byte[] buffer)写一个字节数组进去
public void write(byte[] buffer, int pos, int len)写一个字节数组的一部分进去
public void close() throw IOException关闭流

测试文件(空文件)

写入磁盘一个字节
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;public class Main {public static void main(String[] args) throws IOException {// 首先创建一个内存到硬盘的管道OutputStream fos = new FileOutputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");// 往磁盘中写入一个字节fos.write(97); // 97 ASCII 表示afos.write('b'); // ''  单引号包裹的本来就是一个字节 byte类型fos.close();}
}

也是不能直接写入中文,因为在utf-8编码中,一个中文是占3个字节,这里是只写入一个字节。所以写入中文会乱码,但是我们可以通过写入一个字节数组,来进行添加中文,通过调用StringgetBytes()方法可以得到对应的字节数组

添加中文
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;public class Main {public static void main(String[] args) throws IOException {// 首先创建一个内存到硬盘的管道OutputStream fos = new FileOutputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");// 往磁盘中写入一个字节fos.write(97); // 97 ASCII 表示afos.write('b'); // ''  单引号包裹的本来就是一个字节 byte类型// 添加中文 通过 String 的 getBytes() 方法可以直接得到一个字节数组byte[] bytes = "中文".getBytes();fos.write(bytes);fos.close();}
}
指定添加部分
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;public class Main {public static void main(String[] args) throws IOException {// 首先创建一个内存到硬盘的管道OutputStream fos = new FileOutputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");// 往磁盘中写入一个字节fos.write(97); // 97 ASCII 表示afos.write('b'); // ''  单引号包裹的本来就是一个字节 byte类型// 添加中文 通过 String 的 getBytes() 方法可以直接得到一个字节数组byte[] bytes = "中文".getBytes();fos.write(bytes);// 当然,也可以指定添加的部分byte[] bytes2 = "添加前两个字".getBytes();fos.write(bytes2,0,6); // 一个中文是3个字节,所以添加前两个字,只需要添加6个字节fos.close();}
}

但是上面的添加,都会直接把原先文件里的东西全替代掉。有的时候,我们其实是不想让添加的内容把原先的内容替换掉的,所以就需要创建管道的时候指定是添加的(构造器的第二个参数为true)

后面追加内容

测试文件

文件原本的内容
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;public class Main {public static void main(String[] args) throws IOException {// 首先创建一个内存到硬盘的管道,如果是追加内容,则需要把第二个参数设为trueOutputStream fos = new FileOutputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt",true);// 往磁盘中写入一个字节fos.write(97); // 97 ASCII 表示afos.write('b'); // ''  单引号包裹的本来就是一个字节 byte类型// 添加中文 通过 String 的 getBytes() 方法可以直接得到一个字节数组byte[] bytes = "中文".getBytes();fos.write(bytes);// 当然,也可以指定添加的部分byte[] bytes2 = "添加前两个字".getBytes();fos.write(bytes2,0,6); // 一个中文是3个字节,所以添加前两个字,只需要添加6个字节// 添加换行fos.write("\r\n".getBytes());fos.close();}
}

最后文件显示

文件原本的内容
ab中文添加
文件复制
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class Main {public static void main(String[] args) throws IOException {// 1. 首先创建一个输入流,把需要复制的内容用一个字节数组存储起来FileInputStream fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");// 1.1 创建一个存储字节的数组byte[] bytes = fis.readAllBytes();// 2. 把存起来的字符数组输出到指定的文件里去FileOutputStream fos = new FileOutputStream("D:\\Idea\\Codeing\\Day01\\src\\get.txt", true);fos.write(bytes);fis.close();fos.close();System.out.println("复制完成");}
}

但是上面这种,文件特别大的话,可能会出错。下面有一个更通用的方法

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class Main {public static void main(String[] args) throws IOException {// 1. 首先创建一个输入流,把需要复制的内容用一个字节数组存储起来FileInputStream fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");// 2. 把存起来的字符数组输出到指定的文件里去  这里后面不加true也是追加,因为同一个流不会覆盖FileOutputStream fos = new FileOutputStream("D:\\Idea\\Codeing\\Day01\\src\\get.txt", true);// 3. 创建一个字节数组,负责转移字节数据byte[] bytes = new byte[1024]; // 先给个1kb// 4. 然后开始循环写入int len; // 记录每次读取了多少个字节while ((len = fis.read(bytes)) != -1) {fos.write(bytes,0,len);}fis.close();fos.close();System.out.println("复制完成");}
}
字符输出流
  • Writer抽象类表示,比较常用的实现类是FileWriter
  • 字符输出流输出字符后,必须输出流,或者关闭流,写出去的数据才能生效

作用:

  • 以内存为基准,可以把内存中的数据以字符的形式输出到磁盘中去

首先要创建管道,链接磁盘和内存

构造器说明
public FileWriter(File file)创建字符输出流管道与源文件对象接通
public FileWriter(String pathName)创建字符输出流管道与源文件路径接通
public FileWriter(File file,Boolean append)创建字节输出流管道与源文件对象接通,可追加数据
public FileWriter(String fillpath,boolean append)创建字节输出流管道与源文件路径接通,可追加数据

然后就是方法进行输出

方法名说明
void write(int c)每次写入一个字符,如果发现没有数据可写会返回-1
void write(String str)写一个字符串
void write(String str, int off, int len)写一个字符串的一部分
void write(char[] cbuf)写入一个字符数组
void write(char[] cbuf, int off, int len)写入字符数组的一部分
写入磁盘一个字符
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;public class Main {public static void main(String[] args) {File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");try(// 创建链接管道Writer fw = new FileWriter(f);) {// 一次写入磁盘一个字符fw.write(97);fw.write('b');fw.write('中');// 或者写一个字符串fw.write("国");// 或者写入字符串的一部分fw.write("人123",0,1);} catch (IOException e) {throw new RuntimeException(e);}}
}
写入多个字符
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;public class Main {public static void main(String[] args) {File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");try(// 创建链接管道Writer fw = new FileWriter(f);) {// 写入一个字符数组char[] chars = "1a中".toCharArray();fw.write(chars);// 直接写入一个字符串fw.write("几点开始");} catch (IOException e) {throw new RuntimeException(e);}}
}
关闭流
  • 调用流的close方法即可关闭流的通道。但是有的时候,可能代码会出现一些问题,造成没法办法正常走到close方法,所以就需要错误捕获
tryCatch

try { // 可能会出现错误的代码 } catch (异常类名 变量名) { // 错误处理 } finally { // 不管成功还是失败都一定会执行的 }

  • 除非JVM终止(System.exit()),不然finally里的代码一定会执行的
  • 作用:一般用在程序执行完成后进行资源的释放操作
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Objects;public class Main {public static void main(String[] args) {// 快捷键:选中代码 ctrl + alt + tFileInputStream fis = null;FileOutputStream fos = null;try {// 1. 首先创建一个输入流,把需要复制的内容用一个字节数组存储起来fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");// 2. 把存起来的字符数组输出到指定的文件里去  这里后面不加true也是追加,因为同一个流不会覆盖fos = new FileOutputStream("D:\\Idea\\Codeing\\Day01\\src\\get.txt", true);// 3. 创建一个字节数组,负责转移字节数据byte[] bytes = new byte[1024]; // 先给个1kb// 4. 然后开始循环写入int len; // 记录每次读取了多少个字节while ((len = fis.read(bytes)) != -1) {fos.write(bytes,0,len);}System.out.println("复制完成");} catch (IOException e) {throw new RuntimeException(e);} finally {try {if(Objects.isNull(fis)) fis.close();if(Objects.isNull(fos)) fos.close();} catch (IOException e) {throw new RuntimeException(e);}}}
}
tryWithResource
  • tryCatch更简单
  • 括号里面只能放资源对象,例如流对象,并且会自动关闭流
  • 资源都会实现一个AutoCloseable接口,并且资源都会有一个close方法,并且会自动调用

try(定义资源1; 定义资源2; …) { // 可能出现异常的代码; } carch(异常类名 变量名) { // 异常的处理代码; }

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class Main {public static void main(String[] args) {try(// 1. 首先创建一个输入流,把需要复制的内容用一个字节数组存储起来FileInputStream fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");// 2. 把存起来的字符数组输出到指定的文件里去  这里后面不加true也是追加,因为同一个流不会覆盖FileOutputStream fos = new FileOutputStream("D:\\Idea\\Codeing\\Day01\\src\\get.txt", true);) {// 3. 创建一个字节数组,负责转移字节数据byte[] bytes = new byte[1024]; // 先给个1kb// 4. 然后开始循环写入int len; // 记录每次读取了多少个字节while ((len = fis.read(bytes)) != -1) {fos.write(bytes,0,len);}System.out.println("复制完成");} catch (IOException e) {throw new RuntimeException(e);}}
}

缓冲流

  • 对原始流进行包装,以提高原始流读写数据的性能
字节缓冲输入流

测试数据

abcd

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;public class Main {public static void main(String[] args) {File f = new File("D:\\IDEA\\code\\hello\\src\\test.txt");try(FileInputStream fis = new FileInputStream(f);InputStream bis = new BufferedInputStream(fis);) {byte[] bytes = new byte[3];int len;while ((len = bis.read(bytes)) != -1) { // 不为-1说明就有值System.out.print(new String(bytes, 0, len)); // abcd}} catch (Exception e){e.printStackTrace(); //打印错误信息}}
}
字节缓冲输出流
import java.io.*;public class Main {public static void main(String[] args) {File f = new File("D:\\IDEA\\code\\hello\\src\\test.txt");try(// 建立管道链接OutputStream os = new FileOutputStream(f,true);OutputStream bos = new BufferedOutputStream(os);) {// 一次写入磁盘一个字节bos.write(97); // 97 ASCII中是abos.write('b');// os.write('中'); // 添加中文是不行的,因为在utf8编码中,中文是3个字节,这里只添加一个,肯定不行// 一次写入磁盘多个字节byte[] bytes = "中国".getBytes();bos.write(bytes);// 一次写入指定个数的byte[] bytes1 = "abc".getBytes();bos.write(bytes1, 0, 2);} catch (Exception e){e.printStackTrace(); //打印错误信息}}
}
字符缓冲输入流
import java.io.*;public class Main {public static void main(String[] args) {File f = new File("D:\\IDEA\\code\\hello\\src\\test.txt");try(// 建立管道链接Reader fr = new FileReader(f);Reader br =  new BufferedReader(fr);) {// 1. 一次读取一个字符int r1 = br.read();System.out.println(r1); // 99 ASCII中表示cSystem.out.println((char) r1); // c// 2. 一次读取指定次数的字符char[] chars = new char[4];int len;while ((len = br.read(chars)) != -1) { // 只要不为-1,就说明还有值String s = new String(chars, 0, len);System.out.print(s); // eshishuju}// 3. 一次读取多个字符,并且指定位置和个数int r2 = br.read(chars, 0, 3);System.out.println(r2); // -1 因为上面读完了} catch (Exception e){e.printStackTrace(); // 打印错误信息}}
}
字符缓冲输出流
import java.io.*;public class Main {public static void main(String[] args) {File f = new File("D:\\IDEA\\code\\hello\\src\\test.txt");try(// 建立管道链接Writer fw = new FileWriter(f);Writer bw =  new BufferedWriter(fw);) {// 1. 一次写入磁盘一个字符bw.write(97);bw.write('b');bw.write('中');// 2. 一次写入一个字符数组char[] charArray = "你好呀".toCharArray();bw.write(charArray);// 3. 还可以直接写入字符串,这个就很方便呀bw.write("Java");// 4. 还可以指定起始位置和个数bw.write("Web",0,3);} catch (Exception e){e.printStackTrace(); // 打印错误信息}}
}

转换流

字符输入转换流
InputStreamReader
  • 解决不同编码时,字符读取文本内容乱码的问题
  • 解决思路:先获取文件的原始字节流,再按其真实的字符集编码转成字符输入流,这样字符输入流中的字符就不乱码了
构造器说明
public inputStreamReader(InputStream is)把原始的字节输入流,按照代码默认编码转成字符输入流(与直接用FileReader的效果一样)
public InputStreamReader(InputStream is,String charset)把原始的字节输入流,按照指定字符集编码转成字符输入流

文件A GBK编码格式

中几点开始
import java.io.*;public class Main {public static void main(String[] args) {File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");try(Reader br = new BufferedReader(new FileReader(f));) {// � 因为编译器默认编码是utf8,但是文件里面的编码是gbk 所以乱码了System.out.println((char) br.read());} catch (IOException e) {throw new RuntimeException(e);}}
}

解决办法就是字符输入转换流

import java.io.*;public class Main {public static void main(String[] args) {File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");try(InputStream is = new FileInputStream(f);// 转成对应编码的字节输入流Reader isr = new InputStreamReader(is, "GBK");// 这样再操作就不会有乱码问题了Reader br = new BufferedReader(isr);) {int c;while ((c = br.read()) != -1) {System.out.print((char) c);}} catch (IOException e) {throw new RuntimeException(e);}}
}
字符输出转换流
OutputStreamWrite
  • 可以控制写出去的字符使用什么字符集编码
  • 解决思路:获取字节输出流,再按照指定的字符集编码将其转换为字符输出流,以后写出去的字符就会用该字符集编码了
构造器说明
public OutputStreamWriter(OutStream os)可以把原始的字节输出流,按照代码默认编码转换成字符输出流
public OutputStreamWriter(OutputStream os,String charset)可以把原始的字节输出流,按照指定字符集编码转成字符输出流

文件A GBK编码格式

import java.io.*;public class Main {public static void main(String[] args) {File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");try(Writer bw = new BufferedWriter(new FileWriter(f));) {bw.write("你好呀"); // 啊浣犲ソ鍛�     乱码了,因为写入的是utf8编码的字符} catch (IOException e) {throw new RuntimeException(e);}}
}

解决办法就是字符输出转换流

import java.io.*;public class Main {public static void main(String[] args) {File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");try(OutputStream fos = new FileOutputStream(f, true);// 把原始的字节输入流转成固定格式的输出流Writer psw = new OutputStreamWriter(fos, "GBK");Writer bw = new BufferedWriter(psw);) {bw.write("你好呀"); // 啊你好呀} catch (IOException e) {throw new RuntimeException(e);}}
}
控制写的字符使用的字符集

有两种实现方法:

  1. 调用String提供的getBytes方法

String d = “你好呀”; byte[] bytes = d.getBytes(“GBK”);

  1. 使用字符输出转换流实现

打印流

  • 打印流可以实现更方便,更高效的打印数据出去,能实现打印啥出去就是啥
printStream
  • 属于字节输出流
构造器说明
public PrintStream(OutputStream/File/String)打印流直接通向字节输出流/文件/文件路径
public PrintStream(String fileName,Charset charset)可以指定写出去的字符编码
public PrintStream(OutputStream out, boolean autoFlush)可以指定实现自动刷新
public PrintStream(OutputStream out, bollean autoFlush, String encoding)可以指定实现自动刷新,并可指定字符的编码

写数据的方法

方法名说明
public void println(Xxx xx)打印任意类型的数据出去,自带换行
public void write(int/byte[]/byte[]的一部分)可以支持写字节数据进去

基本使用

import java.io.*;public class Main {public static void main(String[] args) {File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");try(PrintStream ps = new PrintStream(f);) {ps.println(97);ps.println('b');ps.println("你好呀"); // 97 \n b \n 你好呀} catch (IOException e) {throw new RuntimeException(e);}}
}

指定字符集

import java.io.*;
import java.nio.charset.Charset;public class Main {public static void main(String[] args) {File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");try(// 指定写入的编码格式PrintStream ps = new PrintStream(f, Charset.forName("GBK"));) {ps.println(97);ps.println('b');ps.println("你好呀"); // 97 \n b \n 你好呀} catch (IOException e) {throw new RuntimeException(e);}}
}
PrintWriter
  • 属于字符输出流
构造器说明
public PrintWriter(OutputStream/Writer/File/String)打印流直接通向字节输出流/字符输出流/文件/文件路径
public PrintWriter(String fileName,Charset charset)可以指定写出去的字符编码
public PrintWriter(OutputStream out/Writer, boolean autoFlush)可以指定实现自动刷新
public PrintWriter(OutputStream out, bollean autoFlush, String encoding)可以指定实现自动刷新,并可指定字符的编码

写数据的方法

方法名说明
public void println(Xxx xx)打印任意类型的数据出去,自带换行
public void write(int/String/char[])可以支持写字符数据出去

基本使用

import java.io.*;public class Main {public static void main(String[] args) {File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");try(PrintWriter pw = new PrintWriter(f);) {pw.println(97);pw.println('a');pw.println("你好呀"); // 97 \n b \n 你好呀} catch (IOException e) {throw new RuntimeException(e); }}
}

指定字符集

import java.io.*;public class Main {public static void main(String[] args) {File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");try(PrintWriter pw = new PrintWriter(f,"GBK");) {pw.println(97);pw.println('a');pw.println("你好呀");} catch (IOException e) {throw new RuntimeException(e);}}
}
追加数据
  • 因为PrintStreamPrintWriter是高级流,所以不能直接追加数据,但是我们在调用构造器的时候,可以传入一个低级输出流,在低级输出流中可以指定追加
import java.io.*;public class Main {public static void main(String[] args) {File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");try(PrintWriter pw = new PrintWriter(new FileOutputStream(f, true));) {pw.println(97);pw.println('a');pw.println("你好呀");} catch (IOException e) {throw new RuntimeException(e);}}
}
区别
  • 打印数据的功能上一摸一样:都是使用方便,性能高效
  • PrintStream继承字节输出流OutputStream,因此支持字节数据的方法
  • PrintWriter继承字符输出流Writer,因此支持字符数据的方法
应用

输出语句的重定向,可以把输出语句的打印位置改到某个文件中去

import java.io.*;public class Main {public static void main(String[] args) {System.out.println("会打印文件外");File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");try(// PrintWriter pw = new PrintWriter(new FileOutputStream(f));PrintStream ps = new PrintStream(f);) {// 把系统默认的打印流对象改成自己设置的打印流System.setOut(ps);System.out.println("会打印在文件里");} catch (IOException e) {throw new RuntimeException(e);}}
}

数据流

  • 操作的都是字节的
DataOutputStream
  • 属于字节输出流,允许把数据和其类型一并写出去
构造器说明
public DataOutputStream(OutputStream out)创建新数据输出流包装基本的字节输出流

方法

方法说明
public final void writeByte(int v) throws IOException将byte类型的数据写入基本的字节输出流
public final void writeInt(int v) throws IOException将Int类型的数据写入基本的字节输出流
public final void writeDouble(Double v) throws IOException将Double类型的数据写入基本的字节输出流
public final void writeUtf(String str) throws IOException将字符串数据以UTF-8编码字节写入基本的字节输出流
public void write(int/byte[]/byte[]的一部分)支持写字节数据出去

案例

import java.io.*;public class Main {public static void main(String[] args) {File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");try(OutputStream fps = new FileOutputStream(f);// 写入数据和其类型,就需要用到数据流DataOutputStream dos = new DataOutputStream(fps);) {// 写入一个字节dos.writeByte(97); // a// 写入一个数字dos.writeInt(97); // 97// 写入一个布尔dos.writeBoolean(true);// 写入一个小数dos.writeDouble(99.99);// 写入一个字符串dos.writeUTF("你好呀"); // a   a@X�\(� 	你好呀    这不是乱码,是有类型就这样} catch (IOException e) {throw new RuntimeException(e);}}
}
DataInputStream
  • 属于字节输入流,用于读取数据输出流写出去的数据
构造器说明
public DataInputStream(InputStream is)创建新数据输入流包装基本的字节输出流

方法

方法说明
public final void readByte() throws IOException读取字节数据返回
public final int readInt() throws IOException读取int类型的数据返回
public final double readDouble() throws IOException读取double类型的数据返回
public final String readUtf() throws IOException读取字符串数据返回(UTF-8)
public int readInt() / public int read(byte[])支持读字节数据进来

案例:读的顺序要跟写的顺序一样

import java.io.*;public class Main {public static void main(String[] args) {File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");try(InputStream fis = new FileInputStream(f);// 我们需要读取带有值和类型的,所以就需要用到数据输入流DataInputStream dis = new DataInputStream(fis);) {// System.out.println(dis.read()); // 97System.out.println(dis.readByte()); // 97System.out.println(dis.readInt()); // 97System.out.println(dis.readBoolean()); // trueSystem.out.println(dis.readDouble()); // 99.99System.out.println(dis.readUTF()); // 你好呀} catch (IOException e) {throw new RuntimeException(e);}}
}

序列化流

  • 我们想把Java对象存进文件去,就需要用到对象序列化流
  • 则反序列化就是把存进去的对象序列化读取出来
  • 属于字节流
ObjectOutputStream
  • 可以把Java对象进行序列化:把Java对象存入到文件中去
  • transient修饰的成员可以不参与对象序列化
构造器说明
public ObjectOutputStream(OutputStream out)创建对象字节输出流,包装基础的字节输出流

方法

方法名说明
public final void writeObject(Object o) throws IOException把对象写出去

案例

Student.java

package Demo;
import java.io.Serializable;// 注意:对象如果需要序列化,必须实现序列化接口
public class Student implements Serializable {private String name;private int age;// private double score;// transient 修饰,则这个成员变量将不参与序列化(因为有的时候,其实不想要某个属性展示的,例如密码)private transient double score;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getScore() {return score;}public void setScore(double score) {this.score = score;}public Student() {}public Student(String name, int age, double score) {this.name = name;this.age = age;this.score = score;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", score=" + score +'}';}
}

Main.java

import Demo.Student;
import java.io.*;public class Main {public static void main(String[] args) {Student zs = new Student("张三", 25, 100.00);File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");try(OutputStream fos = new FileOutputStream(f);// 我们要写入对象,就需要用到对象序列化流ObjectOutputStream ois = new ObjectOutputStream(fos);) {ois.writeObject(zs);} catch (IOException e) {throw new RuntimeException(e);}}
}
ObjectInputStream
  • 可以把Java对象进行反序列化:把存储在文件中的Java对象读入到内存中来
构造器说明
public ObjectInputStream(InputStream is)创建对象字节输入流,包装基础的字节输入流

方法

方法名说明
public final Object readObject()把存储在文件中的Java对象读出来

案例

import Demo.Student;
import java.io.*;public class Main {public static void main(String[] args) {File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");try(InputStream fis = new FileInputStream(f);// 我们想要读取存储在文件中的对象,就需要对象反序列化ObjectInputStream ois = new ObjectInputStream(fis);) {Student s1 = (Student) ois.readObject();System.out.println(s1);//Student{name='张三', age=25, score=0.0} 这里score并不参与序列化,所以为初始值} catch (Exception e) {e.printStackTrace();}}
}
实现一次多个对象序列化
  • 用一个ArrayList集合存储多个对象,然后直接对集合进行序列化即可
  • ArrayList集合已经实现了序列化接口

Student.java

package Demo;
import java.io.Serializable;// 注意:对象如果需要序列化,必须实现序列化接口
public class Student implements Serializable {private String name;private int age;// private double score;// transient 修饰,则这个成员变量将不参与序列化(因为有的时候,其实不想要某个属性展示的,例如密码)private transient double score;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getScore() {return score;}public void setScore(double score) {this.score = score;}public Student() {}public Student(String name, int age, double score) {this.name = name;this.age = age;this.score = score;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", score=" + score +'}';}
}

写入到磁盘

import Demo.Student;
import java.io.*;
import java.util.ArrayList;public class Main {public static void main(String[] args) {Student zs = new Student("张三", 25, 100.00);Student ls = new Student("李四", 26, 100.00);ArrayList<Student> students = new ArrayList<>();students.add(zs);students.add(ls);File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");try(OutputStream fos = new FileOutputStream(f);// 我们要写入对象,就需要用到对象序列化流ObjectOutputStream ois = new ObjectOutputStream(fos);) {// 把整个ArrayList集合对象写进去,方便我们遍历集合去读ois.writeObject(students);} catch (IOException e) {throw new RuntimeException(e);}}
}

读取磁盘

import Demo.Student;
import java.io.*;
import java.util.ArrayList;public class Main {public static void main(String[] args) {File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");try(InputStream fis = new FileInputStream(f);// 我们想要读取存储在文件中的对象,就需要对象反序列化ObjectInputStream ois = new ObjectInputStream(fis);) {ArrayList<Student> students = (ArrayList<Student>) ois.readObject();System.out.println(students); // [Student{name='张三', age=25, score=0.0}, Student{name='李四', age=26, score=0.0}]} catch (Exception e) {e.printStackTrace();}}
}

IO框架

  • 框架就是解决某类问题,编写的一套类,接口等,可以理解成一个半成品,大多数框架都是第三方研发的

形式:

一般都是把类,接口等编译成class形式,再压缩成一个.jar结尾的文件发行出去

IO框架封装了Java提供的对文件,数据进行操作的代码,对外提供了更简单的方式来对文件进行操作,对数据进行读写等

Commons-io
  • apache开源基金组织提供的一组有关IO操作的小框架,目的是提高IO流的开发效率

FileUtils类

FileUtils类提供的部分方法展示说明
public static void copyFile(File srcFile,File destFile)复制文件
public static void copyDirectory(File srcDir,File destDir)复制文件夹
public static void deleteDirectory(File directory)删除文件夹
public static String readFileToString(File file,String encoding)读数据
public static void writeStringToFile(File file,String data,String charname,boolean append)写数据
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.nio.charset.Charset;public class Main {public static void main(String[] args) {// FileUtilstry {// 拷贝文件FileUtils.copyFile(new File("D:\\Idea\\Codeing\\Day01\\src\\in.txt"),new File("D:\\Idea\\Codeing\\Day01\\src\\out.txt"));// 拷贝文件夹FileUtils.copyDirectory(new File("C:\\Users\\huihui\\Desktop\\in"),new File("C:\\Users\\huihui\\Desktop\\out"));// 删除文件夹(非空的也可以)FileUtils.deleteDirectory(new File("C:\\Users\\huihui\\Desktop\\out"));// 读数据String s = FileUtils.readFileToString(new File("D:\\Idea\\Codeing\\Day01\\src\\in.txt"));System.out.println(s); // 111 不推荐使用这个了// 写数据 不推荐使用这个了FileUtils.writeStringToFile(new File("D:\\Idea\\Codeing\\Day01\\src\\in.txt"), "添加进去");// 追加数据FileUtils.writeStringToFile(new File("D:\\Idea\\Codeing\\Day01\\src\\in.txt"),"追加的数据", Charset.forName("UTF-8"),true);} catch (Exception e) {e.printStackTrace();}}
}

IOUtils类

IOUtils类提供的部分方法展示说明
public static int copy(InputStream inputStream,outputStream outputStream)复制文件
public static int copy(Reader reader,Writer writer)复制文件
public static void write(String data,OutputStream output,String charsetName)写数据

其实Java原生也提供了一些一行代码操作文件的处理(但是都没有成功,不知道为什么)

import java.nio.file.Files;
import java.nio.file.Path;public class Main {public static void main(String[] args) {try {// 拷贝文件// Files.copy(Path.of("Day01\\src\\in.txt"),Path.of("Day01\\src\\out.txt"));// 读文件// System.out.println(Files.readString(Path.of("Day01\\\\src\\\\in.txt"))); //} catch (Exception e) {e.printStackTrace();}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/167076.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通讯协议学习之路:IrDA协议协议理论

通讯协议之路主要分为两部分&#xff0c;第一部分从理论上面讲解各类协议的通讯原理以及通讯格式&#xff0c;第二部分从具体运用上讲解各类通讯协议的具体应用方法。 后续文章会同时发表在个人博客(jason1016.club)、CSDN&#xff1b;视频会发布在bilibili(UID:399951374) 序、…

【CSS】全局滚动条样式设置

直接在 App.vue 全局文件下设置滚动条样式&#xff1a; ::-webkit-scrollbar {width: 5px;position: absolute; } ::-webkit-scrollbar-thumb {background: #1890ff; } ::-webkit-scrollbar-track {background: #ddd; }

Python-Python高阶技巧:闭包、装饰器、设计模式、多线程、网络编程、正则表达式、递归

版本说明 当前版本号[20231018]。 版本修改说明20231018初版 目录 文章目录 版本说明目录Python高阶技巧闭包简单闭包修改外部函数变量的值实现以下atm取钱的闭包实现了闭包注意事项 装饰器装饰器的一般写法&#xff08;闭包写法&#xff09;装饰器的语法糖写法 设计模式单例…

STM32F4_网络通信(网口)

前言 STM32F4开发板上自带了网口。可以通过开发板自带的网口和LWIP实现&#xff1a;TCP服务器、TCP客服端、UDP以及WEB服务器等四个功能。 1. STM32 以太网简介 STM32F4 芯片自带以太网模块&#xff0c;该模块包括带有专用 DMA 控制器的 MAC 802.3&#xff08;介质访问控制&am…

计算机算法分析与设计(12)---贪心算法(最优装载问题和哈夫曼编码问题)

文章目录 一、最优装载问题1.1 问题表述1.2 代码编写 二、哈夫曼编码2.1 哈夫曼编码概述2.2 前缀码2.3 问题描述2.4 代码思路2.5 代码编写 一、最优装载问题 1.1 问题表述 1. 有一批集装箱要装上一艘载重量为 c c c 的轮船&#xff0c;已知集装箱 i ( 1 ≤ i ≤ n ) i(1≤i≤…

【Matlab】三维绘图函数汇总

本文用于汇总 Matlab 中的三维绘图函数。plot3() 函数用于绘制用参数方程表示的三维曲线。ezplot3() 函数用于三维曲线的符号绘图&#xff0c;需要用参数方程表示。mesh() 函数用于绘制三维曲面网格。surf() 函数用于绘制三维空间曲面。 目录 1. plot3() 2. ezplot3() 3. me…

R文件详细介绍、瘦身方案和原理

文章目录 1. 背景2. R文件介绍2.1 R文件概念2.1.1 标识符是怎么与资源联系起来的&#xff1f; 2.2 R文件内容2.3 library module和aar的R文件内容生成规则2.4 是谁生成的R文件&#xff1f;2.5 打包之后的R文件2.6 R文件为啥大&#xff1f;这么多&#xff1f; 3. 为什么R文件可以…

【Objective-C】浅析Block及其捕获机制

目录 Block的基本使用Block的声明Block的实现Block的调用 Block作为形参使用Block作为属性使用给Block起别名Block的copy Block的捕获机制auto类型的局部变量__block浅析static类型的局部变量全局变量 其他问题 Block的基本使用 什么是Block&#xff1f; Block &#xff08;块…

2.2.C++项目:网络版五子棋对战之数据管理模块的设计

文章目录 一、数据管理模块实现&#xff08;一&#xff09;功能 二、设计&#xff08;一&#xff09;数据库设计&#xff08;二&#xff09;创建user_table类 一、数据管理模块实现 &#xff08;一&#xff09;功能 数据管理模块主要负责对于数据库中数据进行统一的增删改查管…

【快速解决】在vs2022中配置SFML图形库

目录 SFML 图形库的安装步骤如下&#xff1a; 1.下载 SFML 在 SFML 的官网&#xff08;下载对应操作系统版本的 SFML&#xff09;。​编辑 2.解压文件 将下载的压缩包解压至任意位置&#xff0c;得到类似如下的目录结构&#xff1a; 3.配置 VS 打开 Visual Studio&#xff…

人工智能、机器学习、深度学习的区别

人工智能涵盖范围最广&#xff0c;它包含了机器学习&#xff1b;而机器学习是人工智能的重要研究内容&#xff0c;它又包含了深度学习。 人工智能&#xff08;AI&#xff09; 人工智能是一门以计算机科学为基础&#xff0c;融合了数学、神经学、心理学、控制学等多个科目的交…

深度学习_3_实战_房价预测

梯度 实战 代码&#xff1a; # %matplotlib inline import random import torch import matplotlib.pyplot as plt # from d21 import torch as d21def synthetic_data(w, b, num_examples):"""生成 Y XW b 噪声。"""X torch.normal(0,…

Java EE-servlet API 三种主要的类

上述的代码如下&#xff1a; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.i…

使用CMake构建一个简单的C++项目

文章目录 一. 构建一个简单的项目二. 构建过程1. 创建程序源文件2. 编写CMakeList.txt文件3. 构建项目并编译源代码 附件 一. 构建一个简单的项目 最基本的CMake项目是从单个源代码文件构建的可执行文件。对于像这样的简单项目&#xff0c;只需要一个包含三个命令的CMakeLists…

查看当前cmake版本支持哪些版本的Visual Studio

不同版本的的cmake对Visual Studio的版本支持不同&#xff0c;以下图示展示了如何查看当前安装的cmake支持哪些版本的Visual Studio。 1.打开cmake-gui 2.查看cmake支持哪些版本的Visual Studio

django基于Python的房价预测系统+爬虫+大屏可视化分析

欢迎大家点赞、收藏、关注、评论 文章目录 前言一、项目介绍二、开发环境三、功能需求分析1 数据采集功能设计2数据管理功能设计3爬虫功能需求分析4 数据可视化功能需求分析数据库表的设计 四、核心代码五、效果图六、文章目录 前言 房价是一个国家经济水平的重要体现&#xff…

正点原子嵌入式linux驱动开发——Linux并发与竞争

Linux是一个多任务操作系统&#xff0c;肯定会存在多个任务共同操作同一段内存或者设备的情况&#xff0c;多个任务甚至中断都能访问的资源叫做共享资源。在驱动开发中要注意对共享资源的保护&#xff0c;也就是要处理对共享资源的并发访问。在Linux驱动编写过程中对于并发控制…

2、Kafka 生产者

3.1 生产者消息发送流程 3.1.1 发送原理 在消息发送的过程中&#xff0c;涉及到了两个线程——main 线程和 Sender 线程。在 main 线程 中创建了一个双端队列 RecordAccumulator。main 线程将消息发送给 RecordAccumulator&#xff0c; Sender 线程不断从 RecordAccumulator 中…

为什么短信验证码要设置有效期?

安全性&#xff1a;验证码的主要目的是为了验证用户的身份&#xff0c;防止恶意或未经授权的访问。如果验证码没有有效期&#xff0c;恶意用户或攻击者可以获取验证码后无限期地尝试使用它。通过设置有效期&#xff0c;可以限制验证码的生命周期&#xff0c;提高系统的安全性。…

跳跃游戏Ⅱ-----题解报告

题目&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 与Ⅰ不同的是&#xff0c;这次要求找出最小的跳跃次数。思路也很简单&#xff0c;在每一次跳跃之后都更新最远的跳跃距离。 举个列子&#xff1a; 输入&#xff1a;2,3,1,1,4 第一次…