练习1:拷贝文件夹
分析:自己写的有点混乱,思路也不对。
public class IO5 {
public static void main(String[] args) throws IOException {
//拷贝文件夹
//首先先有这样一个文件夹
File file = new File("src/com/liu");
copy(file);
}
private static void copy(File file) throws IOException {
//新文件夹
// 1. 先获取文件夹的名字
String path = "aaa/" + file.getName();
// 2. 创建文件夹要存储的路径File对象
File dir = new File(path);
// 3. 创建文件夹
dir.mkdirs();
//原来文件夹下的所有内容
File[] files = file.listFiles();
for (File f : files) {
if (f.isDirectory()) {
copy(f);
} else {
// 为文件创建一个读取流
FileInputStream fis = new FileInputStream(f);
int b;
while ((b = fis.read()) != -1) {
File destionation = new File(path + "/" + f.getName());
destionation.createNewFile();
FileOutputStream fos = new FileOutputStream(destionation);
fos.write(b);
}
}
}
}
}
修改:将此文件夹拷贝到哪个目录下,所以有两个路径,分别是表示此文件夹的from和到哪个目录下to 。
然后如何拷贝呢?
首先要把新的目标文件夹创建出来:获取此文件夹的名字,然后创建到to目录下。
然后把文件夹下的所有内容都拷贝到新的目标文件夹下
如果是文件,则路径是:new File(newDir, f.getName()),这里我刚开始是使用+进行拼接的,其实这样不对,应该是使用File的2个参数的构造方法。
而如果是文件夹,则递归调用此方法,但需要注意路径的传递:copy(f, newDir)。
public class IO6 {
public static void main(String[] args) throws IOException {
File from = new File("src/com/liu");
File to = new File("bbb");
copy(from, to);
}
private static void copy(File from, File to) throws IOException {
// 创建新的目标文件夹
File newDir = new File(to, from.getName());
newDir.mkdirs();
// 处理原文件夹下的所有内容
File[] files = from.listFiles();
for (File f : files) {
if (f.isDirectory()) {
copy(f, newDir); // 递归处理子文件夹
} else {
// 为文件创建读取流和写入流
FileInputStream fis = new FileInputStream(f);
FileOutputStream fos = new FileOutputStream(new File(newDir, f.getName()));
// 使用缓冲区提高效率
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
// 关闭流
fos.close();
fis.close();
}
}
}
}
练习2: 加密和解密文件
为了保证文件的安全性,就需要对原始文件进行加密存储,再使用的时候再对其进行解密处理。
加密原理:对原始文件中的每一个字节数据进行更改,然后将更改以后的数据存储到新的文件中,
解密原理:读取加密之后的文件,按照加密的规则反向操作,变成原始文件。
这里需要介绍一个知识点就是:一个二进制数①与另外一个二进制数②进行异或得到一个值,当这个值再与②进行异或的话,就能得到原来的二进制①。
所以可以利用这个进行加密和解密。
加密的实现:
public class IO7 {
public static void main(String[] args) throws IOException {
// 要读取的文件肯定是要存在的
FileInputStream fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\image-20240722173741395.png");
// 要写入到哪里
FileOutputStream fos = new FileOutputStream("111.jpg");
int b;
while((b = fis.read()) != -1) {
fos.write(b ^ 10);
}
fos.close();
fis.close();
}
}
解密的实现:
public class IO8 {
public static void main(String[] args) throws IOException {
// 要读取的文件
FileInputStream fis = new FileInputStream("111.jpg");
// 要写入到哪里
FileOutputStream fos = new FileOutputStream("222.png");
int b;
while((b = fis.read()) != -1) {
fos.write(b ^ 10);
}
fos.close();
fis.close();
}
}
练习3: 修改文件中的数据
文本文件中有以下的数据:2-1-9-4-7-8
将文件中的数据进行排序,变成以下的数据:1-2-4-7-8-9
分析:1、首先将文件中的所有数据读取出来,放到StringBuilder中再转换为字符串。
2、提取其中的数字,由于是字符串,所以使用parseInt()方法将字符串转换为整数。
集合中有一个工具类Collections,里面有一个sort方法可以对整数升序排列。
3、如何再把整数写进去呢?
由于集合中存的是整数,把整数一个一个地和空字符串“”进行拼接转换为字符串①,然后再利用write方法逐个写入。
这里我是使用字节输出流的write(int b)方法,需要①调用getBytes()方法转换为字节。
其实还可以使用字符输出流,可以直接写入字符串①,就不需要再getBytes()方法转换为字节了。
public class IO9 {
public static void main(String[] args) throws IOException {
// 首选读取文件
FileInputStream fis = new FileInputStream("a.txt");
int b;
StringBuilder sb = new StringBuilder();
while ((b = fis.read()) != -1) {
sb.append((char)b);
}
// 把其中的整数提取出来并排序
String s = sb.toString();
String[] ss = s.split("-");
ArrayList<Integer> list = new ArrayList<>();
for (String s1 : ss) {
list.add(Integer.parseInt(s1));
}
Collections.sort(list);
System.out.println(list);
// 写到新文本中
FileOutputStream fos = new FileOutputStream("b.txt");
int len = list.size();
for (int i = 0; i < len; i++) {
if (i == len -1) {
fos.write((list.get(i) + "").getBytes());
} else {
fos.write((list.get(i) + "").getBytes());
fos.write("-".getBytes());
}
}
}
}
修改:
还有另外一种方式的实现,可以对第2步和第3步改进。
第2步还可以使用Stream流。
这里我是使用collect()方法将结果收集到List中了。然后还是使用Collections里的sort方法对集合中的整数升序排列。
// 还可以使用Stream流把其中的整数提取出来并排序
String s = sb.toString();
String[] ss = s.split("-");
List<Integer> list = Arrays.stream(ss)
.map(Integer::parseInt)
.collect(Collectors.toList());
Collections.sort(list);
在Java中,Stream中的sorted方法可以对流中的数据进行排列,toArray方法可以将流中的元素收集到一个数组中。
Integer[] list = Arrays.stream(ss)
.map(Integer::parseInt)
.sorted()
.toArray(Integer[]::new);
第3步其实可以利用toString方法将集合整个转换为字符串,直接一下全部写入,不用再一个一个写入了。
String str = list.toString().replace(", ", "-");
String substr = str.substring(1, str.length() - 1);
FileWriter fw = new FileWriter("b.txt");
fw.write(substr);
fw.close();
在使用IDEA的快捷键提示功能时,要注意提示的变量是否正确。