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.mzph.cn/news/114728.shtml

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

相关文章

智慧公厕蜕变多功能城市智慧驿站公厕的创新

随着城市发展的不断推进&#xff0c;对公共设施的便利性和智能化要求也日益提高。为满足市民对高品质、便捷、舒适的公共厕所的需求&#xff0c;智慧公厕行业的领航厂家广州中期科技有限公司&#xff0c;全新推出了一体化智慧公厕驿站。凭借着“高科技碳中和物联网创意设计新经…

【Java基础面试四十二】、 static修饰的类能不能被继承?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a; static修饰的类能不能被…

设计模式-责任链设计模式

核心思想 客户端发出一个请求&#xff0c;链上的对象都有机会来处理这一请求&#xff0c;而客户端不需要知道谁是具体的处理对象让多个对象都有机会处理请求&#xff0c;避免请求的发送者和接收者之间的耦合关系&#xff0c;将这个对象连成一条调用链&#xff0c;并沿着这条链…

Node学习笔记之HTTP 模块

回顾&#xff1a;什么是客户端、什么是服务器&#xff1f; 在网络节点中&#xff0c;负责消费资源的电脑&#xff0c;叫做客户端&#xff1b;负责对外提供网络资源的电脑&#xff0c;叫做服务器。 http 模块是 Node.js 官方提供的、用来创建 web 服务器的模块。通过 http 模块…

用Python获取网络数据

用Python获取网络数据 网络数据采集是 Python 语言非常擅长的领域&#xff0c;上节课我们讲到&#xff0c;实现网络数据采集的程序通常称之为网络爬虫或蜘蛛程序。即便是在大数据时代&#xff0c;数据对于中小企业来说仍然是硬伤和短板&#xff0c;有些数据需要通过开放或付费…

为什么嵌入通常优于TF-IDF:探索NLP的力量

塔曼纳 一、说明 自然语言处理&#xff08;NLP&#xff09;是计算机科学的一个领域&#xff0c;涉及人类语言的处理和分析。它用于各种应用程序&#xff0c;例如聊天机器人、情绪分析、语音识别等。NLP 中的重要任务之一是文本分类&#xff0c;我们根据文本的内容将文本分类为不…

UE4逆向篇-2_各类数据的查找方式

写在前面 1.通过前面的文章&#xff0c;相信各位已经能够自己找到GNames并使用DUMP工具导出GNames了。 2.本篇文章将介绍各种所需数据的查找方法。 一、准备工作 1.CheatEngine&#xff0c;本篇以及后续篇幅的重要工具。 2.一个记事本&#xff0c;保证你能记录下关键信息。…

ubuntu启动模式介绍以及如何进入单用户模式和恢复模式

Ubuntu操作系统提供了多种启动模式&#xff0c;每种模式都有不同的用途和功能。下面将深入介绍Ubuntu的几种启动模式&#xff1a; 正常启动模式&#xff08;Normal boot&#xff09;&#xff1a;这是默认的启动模式&#xff0c;也是大多数用户使用的模式。在正常启动模式下&am…

在Mac上使用安卓桌面模式

在安装Homeblew的基础上 替换国内源 export HOMEBREW_API_DOMAIN"https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles/api" export HOMEBREW_BREW_GIT_REMOTE"https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git" brew update 安装Scrcpy …

屏幕录像推荐:Apeaksoft Screen Recorder 中文 for mac

Apeaksoft Screen Recorder 是一款功能强大的屏幕录制软件&#xff0c;它允许用户在 Windows 和 Mac 系统上捕捉和录制屏幕活动。无论是记录游戏过程、创建教学视频、制作演示文稿还是捕捉在线流媒体内容&#xff0c;该软件都提供了丰富的功能和工具。 以下是 Apeaksoft Scree…

【MATLAB源码-第52期】基于matlab的4用户DS-CDMA误码率仿真,对比不同信道以及不同扩频码。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 1. DS-CDMA系统 DS-CDMA (Direct Sequence Code Division Multiple Access) 是一种多址接入技术&#xff0c;其基本思想是使用伪随机码序列来调制发送信号。DS-CDMA的特点是所有用户在同一频率上同时发送和接收信息&#xf…

《动手学深度学习 Pytorch版》 9.4 双向循环神经网络

之前的序列学习中假设的目标是在给定观测的情况下对下一个输出进行建模&#xff0c;然而也存在需要后文预测前文的情况。 9.4.1 隐马尔可夫模型中的动态规划 数学推导太复杂了&#xff0c;略。 9.4.2 双向模型 双向循环神经网络&#xff08;bidirectional RNNs&#xff09;…

Ubuntu 17.10的超震撼声音权限

从GNOME GUADEC 2017开发者大会归来之后&#xff0c;Canonical的Didier Roche就开始了一个日更博客系列&#xff0c;主要讲述即将带来的Ubuntu 17.10&#xff08;Artful Aardvark&#xff09;发行版将如何从Unity到GNOME Shell的转变。有趣的是&#xff0c;Ubuntu Unity桌面环境…

gin框架39--重构 BasicAuth 中间件

gin框架39--重构 BasicAuth 中间件 介绍gin BasicAuth 解析自定义newAuth实现基础认证注意事项说明 介绍 每当我们打开一个网址的时候&#xff0c;会自动弹出一个认证界面&#xff0c;要求我们输入用户名和密码&#xff0c;这种BasicAuth是最基础、最常见的认证方式&#xff0…

SIEMENS S7-1200 汽车转弯灯程序 编程与分析

公告 项目地址:https://github.com/MartinxMax/SIEMENS-1200-car_turn_signal 分析 题目: 画IO分配表 输入输出m3.0左转弯开关q0.0左闪灯m3.1右转弯开关q0.1右闪灯m3.2停止开关 博图V16配置 设置PLC的IP地址 允许远程通信访问 将HMI设备拖入 注意,我们这边选择的是HMI连接…

数据结构----算法--五大基本算法(这里没有写分支限界法)和银行家算法

数据结构----算法–五大基本算法&#xff08;这里没有写分支限界法&#xff09;和银行家算法 一.贪心算法 1.什么是贪心算法 在有多个选择的时候不考虑长远的情况&#xff0c;只考虑眼前的这一步&#xff0c;在眼前这一步选择当前的最好的方案 二.分治法 1.分治的概念 分…

【JavaEE】Callable 接口

Callable 是一个 interface . 相当于把线程封装了一个 “返回值”. 方便程序猿借助多线程的方式计算结果. 实现Callable也是创建线程的一种方法&#xff01;&#xff01;&#xff01;&#xff01; Callable的用法非常接近于Runnable&#xff0c;Runnable描述了一个任务&#…

Mysql创建视图中文乱码修改docker里的配置

问题现象&#xff1a; 创建的视图查询无数据&#xff0c;查看创建语句得知&#xff0c;where条件里的中文变成了“???”。 在客户端里查询字符编码&#xff1a; show VARIABLES like %char%;就是character_set_server导致的&#xff0c;它配置的竟然不是utf8&#xff0c;…

通过SVN拉取项目 步骤

方法一&#xff1a;文件夹方式 首先新建一个空的文件夹&#xff0c;例如&#xff0c;名为“demo”的空文件夹 在这个空的文件夹中鼠标右键&#xff0c;点击SVN Checkout 会出现下图所示的页面&#xff0c;第一个输入框是svn的项目地址&#xff0c;第二个输入框是拉取项目所放的…