练习1:拷贝文件
四种方式拷贝文件,并统计各自用时。
字节流的基本流:一次读写一个字节
字节流的基本流:一次读写一个字节数组
字节缓冲流:一次读写一个字节
字节缓冲流:一次读写一个字节数组
这里我只使用了字节缓冲流进行实现,分别是一次读写一个字节和一次读写一个字节数组。
我写的时候还有一个问题就是我搁那拷贝文件夹呢,一直出现 D:\垃圾邮件\chinese-spam-filter-master (拒绝访问。)这种错误,原因就是流操作的是文件,路径不对,解决了半天。
java
public class BIO4 {
public static void main(String[] args) throws IOException {
//method1();
method2();
}
private static void method1() throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\Java学习资料\\day10-字符串\\笔记\\常用API.md"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bbb.md"));
int b;
long startTime = System.currentTimeMillis();
while ((b = bis.read()) != -1) {
bos.write(b);
}
long endTime = System.currentTimeMillis();
bos.close();
bis.close();
System.out.println(endTime - startTime);
}
private static void method2() throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\Java学习资料\\day10-字符串\\笔记\\常用API.md"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bbb.md"));
byte[] buffer = new byte[1024 * 1024 * 5];
int len;
long startTime = System.currentTimeMillis();
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
long endTime = System.currentTimeMillis();
bos.close();
bis.close();
System.out.println(endTime - startTime);
}
}
练习2: 修改文本顺序
需求:把《出师表》的文章按顺序恢复到一个新的文件中。
下面就是需要恢复顺序的《出师表》的文章,前面的序号是文章的正确顺序。
3.侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉以咨之,然后施行,必得裨补阙漏,有所广益。
8.愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏,臣不胜受恩感激。
4.将军向宠,性行淑均,晓畅军事,试用之于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。
2.宫中府中,俱为一体,陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。
1.先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。
9.今当远离,临表涕零,不知所言。
6.臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。
7.先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐付托不效,以伤先帝之明,故五月渡泸,深入不毛。今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所以报先帝而忠陛下之职分也。至于斟酌损益,进尽忠言,则攸之、祎、允之任也。
5.亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也。
首先需要把文章中的所有内容读取出来之后,才能进行后续的操作,所以要先放到集合中。至于是哪种集合则需要根据需求进行考虑。
分析:
- 读取文章的所有内容放到集合中;
- 对集合中的内容按照规则进行排序;
- 再写入到文件中。
关于步骤1没什么好说的,都一样,但是选取的集合有两种。
实现一:
首先考虑到的就是TreeMap集合,因为可以进行排序。
关于写入文件在这里是集合中的元素一个一个单独写入的。
java
public class BIO5 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("bbb//csb.txt"));
String str;
TreeMap<Integer, String> tm = new TreeMap<>();
while ((str = br.readLine()) != null) {
String[] s = str.split("\\.");
tm.put(Integer.parseInt(s[0]), s[1]);
}
br.close();
// 将汉字写入
BufferedWriter bw = new BufferedWriter(new FileWriter("bbb//copy.txt"));
for (Integer i : tm.keySet()) {
String s = tm.get(i);
bw.write(s);
bw.newLine();
}
bw.close();
其实还可以一下全部写入:采用toString()方法将集合中的内容转换为字符串。
java
String s = tm.toString().replace(", ", "\n").replace("=", ".");
bw.write(s);
bw.close();
实现二:视频里还有一种思路用的是ArrayList集合。
全部元素添加完成后使用集合工具类Collections的sort方法进行排序,并指定排序规则。这个方法虽然也可以实现,但我觉得并不是很好,因为有可排序的集合存在,要挑选更好的使用。
java
BufferedReader br = new BufferedReader(new FileReader("bbb//csb.txt"));
String str;
ArrayList<String> list = new ArrayList<>();
while ((str = br.readLine()) != null) {
list.add(str);
}
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int i1 = Integer.parseInt(o1.split("\\.")[0]);
int i2 = Integer.parseInt(o2.split("\\.")[0]);
return i1 - i2;
}
});
Tips:当向文件中写入数据时没有关闭流时会发现数据并没有写入,是因为没有把数据刷新进去。
练习3:软件运行次数
实现一个验证程序运行次数的小程序,要求如下:
1.当程序运行超过3次时给出提示:本软件只能免费使用3次,欢迎您注册会员后继续使用~
2.程序运行演示如下:
第一次运行控制台输出:欢迎使用本软件,第1次使用免费~
第二次运行控制台输出:欢迎使用本软件,第2次使用免费~
第三次运行控制台输出:欢迎使用本软件,第3次使用免费~
第四次及之后运行控制台输出:本软件只能免费使用3次,欢迎您注册会员后继续使用~
在这个练习中以前都是在程序中运行,与内存打交道,程序运行结束时数据就不存在了。但是现在学习了IO,就可以将数据写入到外部文件中了,将数据进行保存。
分析:
1、运行程序时首先读取文件中保存的次数;
2、然后进行比较再决定是否写入。
代码实现:
java
public class BIO7 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("bbb/count.txt"));
String s = br.readLine();
BufferedWriter bw = new BufferedWriter(new FileWriter("bbb/count.txt"));
if (s == null) {
bw.write("1");
System.out.println("欢迎使用本软件,第1次使用免费~");
} else {
int count = Integer.parseInt(s);
if (count >= 3) {
System.out.println("本软件只能免费使用3次,欢迎您注册会员后继续使用~");
} else {
count++;
bw.write(Integer.toString(count));
System.out.println("欢迎使用本软件,第"+ count +"次使用免费~");
}
}
bw.close();
br.close();
}
}
但是在视频中却是先创建出文件,然后手动写入次数0。
问题:-1转换为char类型的值为什么是'\uFFFF' ?
在Java中,char 类型是一个 16 位的无符号整数,范围从 0 到 65535(即 0x0000 到 0xFFFF)。当你将一个整数赋给 char 类型时,会发生强制类型转换,整数的值将被解释为对应的 Unicode 字符。
如果你将整数 -1 转换为 char 类型,实际上是将其视为 Unicode 码点 0xFFFF,即特殊符号 REPLACEMENT CHARACTER(�),它通常表示未知字符或无法识别的字符。
下面是将 -1 转换为 char 类型的示例代码:
java
int num = -1;
char ch = (char) num;
System.out.println("Unicode code point of -1 is: " + (int) ch); // 输出 65535
System.out.println("Character represented by -1 is: " + ch); // 输出 \uFFFF