前言

b站java课程学习笔记整理。

b站视频: 黑马程序员全套Java教程_Java基础入门视频教程,零基础小白自学Java必备教程

309. 复制单级文件夹

需求:把一个文件夹下的所有文件复制到指定的位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package 文件夹的复制;

import java.io.*;

public class Demo {
public static void main(String[] args) throws IOException {
// 创建数据源目录对象
File srcFolder = new File("E:\\Javacode\\JavaSE Code\\rookie");
//获取数据源目录的名称
String folderName = srcFolder.getName();

// 创建目的地目录
File destFolder = new File("idea_test",folderName);

// 如果目的地目录不存在,就新建一个目录
if(!destFolder.exists()){
destFolder.mkdir();
}

// 创建一个文件数组,读取数据源目录下所有文件
File[] listFiles = srcFolder.listFiles();

// 写文件
for(File srcFile:listFiles){
String srcFileName = srcFile.getName();
File destFile = new File(destFolder,srcFileName);
copyFile(srcFile,destFile);
}


}

private static void copyFile(File srcFile, File destFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));

byte[] bys = new byte[1024];
int len;
while((len = bis.read())!=-1){
bos.write(bys,0,len);
}

bis.close();
bos.close();
}
}

310. 复制多级文件夹

用递归。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package 文件夹的复制;

import java.io.*;

public class DuoJiDemo {
public static void main(String[] args) throws IOException {
// 创建数据源目录对象
File srcFile = new File("E:\\Javacode\\JavaSE Code\\theshy");
// 创建目的地对象
File destFile = new File("idea_test");
// 使用copyFolder方法
copyFolder(srcFile,destFile);


}
private static void copyFolder(File srcFile, File destFile) throws IOException {
//如果是文件夹
if(srcFile.isDirectory()){
// 在目的地下查找同名目录,如果没有就创建个新的
String srcFilename = srcFile.getName(); // “一个文件夹”
File newFolder = new File(destFile,srcFilename); // “idea_test\\一个文件夹”
if(!newFolder.exists()){
newFolder.mkdir();
}
File[] fileList = srcFile.listFiles();
for(File file:fileList){
copyFolder(file,newFolder); //递归,新的文件夹地址取代了destFile。
}
}else{
File newFile = new File(destFile,srcFile.getName());
copyFile(srcFile,newFile);
}
}
private static void copyFile(File srcFile, File destFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));

byte[] bys = new byte[1024];
int len;
while((len = bis.read())!=-1){
bos.write(bys,0,len);
}

bis.close();
bos.close();
}
}

有点难,注意理解。

311. 复制文件夹的异常处理

保准的使用try...catch...finally处理。 JDK7的改进方案:

1
2
3
4
5
6
try(定义流对象){
可能有问题的代码;
}catch(异常类名 变量名){
异常的处理代码
}
自动释放资源

JDK9的改进方案:

1
2
3
4
5
6
7
8
9
定义输入流对象
定义输出流对象
try(输入流对象;输出流对象e){
可能有问题的代码;
}catch(异常类名 变量名){
异常的处理代码
}
自动释放资源

四种完整的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package 复制文件的异常处理;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class demo {
public static void main(String[] args) {

}

// 方法一: 直接抛出
private static void method1() throws IOException {
FileWriter fw = new FileWriter("java.txt");
FileReader fr = new FileReader("idea_test\\java.txt");
char[] chars = new char[1024];
int len;
while ((len = fr.read()) != -1) {
fw.write(chars, 0, len);
}
}

// 方法二: 标准化处理
private static void method2() {
FileWriter fw = null;
FileReader fr = null;
try {
fw = new FileWriter("java.txt");
fr = new FileReader("idea_test\\java.txt");
char[] chars = new char[1024];
int len;
while ((len = fr.read()) != -1) {
fw.write(chars, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fw == null){
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fr== null){
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 方法三: JDK7
private static void method3() {
try (FileWriter fw = new FileWriter("java.txt");
FileReader fr = new FileReader("idea_test\\java.txt")){
char[] chars = new char[1024];
int len;
while ((len = fr.read()) != -1) {
fw.write(chars, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}

// 方案四: JDK9
private static void method4() throws IOException {
FileWriter fw = new FileWriter("java.txt");
FileReader fr = new FileReader("idea_test\\java.txt");
try (fw;fr){
char[] chars = new char[1024];
int len;
while ((len = fr.read()) != -1) {
fw.write(chars, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}

}

312. 标准输入流

System类中有两个静态的成员变量:

  • public static final InputStream in 标准输入流。
  • public static final PrintStream out 标准输出流。

自己实现键盘录入数据:

  • BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

原理就是把系统的标准输入流(字节输入流)转换为字符输入流,再包装成缓冲输入流,之后就可以使用readLine方法了。

这就是Scanner的底层原理。

313. 标准输出流

System.out的本质就是一个字节输出流。

sout 就是System.out.Println() 就是字节输出流的一种使用。

314. 字节打印流

打印流分类:

  • 字节打印流: PrintStream
  • 字符打印流:PrintWriter

打印流的特点:

  • 只负责输出数据,不负责读取数据
  • 有自己的特有方法

字节打印流

  • PrintStream(String fileName): 使用指定的文件名创建新的打印流。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package 字节打印流;

import java.io.IOException;
import java.io.PrintStream;

public class Demo {
public static void main(String[] args) throws IOException {
PrintStream ps = new PrintStream("idea_test\\rookie\\java.txt");

ps.write(97);

ps.print(97);
ps.println(98);
ps.println(false);

ps.close();
}
}

特有方法printprintln,使用这两种方法,到txt文档没有转码,写多少就是多少。

315. 字符打印流

方法名 说明
PrintWriter(String fileName) 使用指定的文件名创建一个新的PrintWriter,而不需要自动执行刷新
PrintWriter(Writer out, boolean autoFlush) 创建一个新的PrintWriter
out:字符输出流
autoFlush:一个布尔值,如果为真,则printlnprintf,或者format方法将刷新输出缓冲区

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package 字符打印流;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class Demo {
public static void main(String[] args) throws IOException {
PrintWriter pw = new PrintWriter("idea_test\\java.txt");
pw.println("hello");
pw.flush();
pw.println("world");
pw.flush();
pw.close();


PrintWriter pw2 = new PrintWriter(new FileWriter("idea_test\\java.txt"),true);
pw2.println("ni");
pw2.println("hao");
pw2.close();
}
}

316. 复制java文件打印流改进版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package 复制java文件打印流改进版;

import java.io.*;

public class Demo {
public static void main(String[] args) throws IOException {
String source = "E:\\Javacode\\JavaSE Code\\rookie\\rookie.java";
String destination = "E:\\Javacode\\JavaSE Code\\theshy\\theshy.java";

BufferedReader br = new BufferedReader(new FileReader(source));
PrintWriter pw = new PrintWriter(new FileWriter(destination),true);

String line;
while((line=br.readLine())!=null){
pw.println(line);
}

br.close();
pw.close();



}
}

总结:用这个,这个简单。

317. 对象序列化流

就是把一个对象写入一个文件中。

对象序列化流:ObjectOutputStream

  • 将Java对象的原始数据类型和图形写入OutputStream。可以使用ObjectInputStream读取(重构)对象。可以通过使用流的文件来实现对象的持久存储。如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象。

构造方法:

  • ObjectOutputStream(OutputStream out): 创建一个写入指定的OutputStreamObjectOutputStream

序列化对象的方法:

  • void writeObject(Object obj): 将指定的对象写入ObjectOutputStream
注意:

需要写入的类必须实现序列化接口Serializable。这个接口不需要重写方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package 对象序列化流;

import java.io.Serializable;

public class Student implements Serializable {

private int age;

private String name;

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 Student(String name, int age) {
System.out.println("使用带参方法定义");
this.name = name;
this.age = age;
}

public Student() {
System.out.println("使用无参方法定义");
}

public void getInfo() {
System.out.println("学生名为" + name);
System.out.println("学生年龄为" + age);
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package 对象序列化流;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Demo {
public static void main(String[] args) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("java.txt"));
Student s = new Student("林青霞",30 );
oos.writeObject(s);

oos.close();
}
}

318. 对象的反序列化流

构造方法:

  • ObjectInputStream(InputStream in): 创建从指定的InputStream读取的ObjectInputStream

反序列化对象的方法:

  • Object readObject(): 从ObjectInputStream读取一个对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package 对象反序列化流;

import 对象序列化流.Student;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class Demo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("java.txt"));
Object obj = ois.readObject();

Student s = (Student) obj;

s.getInfo();

ois.close();
}

}

注意: 反序列化流里的Student类要和序列化流的类一致,不然就会报错ClassNotFoundException

319. serialVersionUID&transient

在序列化写入对象时,类会获取一个ID,在修改类后,类会获取一个新ID。这会导致类版本不匹配的报错问题。

解决方案:让这个类提前声明一个ID,并用private进行修饰。

示例代码:

1
private static final long serialVersionUID = 42L;

如果一个变量不想被序列化,那就用transient修饰。

示例代码:

1
pritave transient String name;

320. Properties作为Map集合的使用

Properties是一个Map体系的集合类,可以保存在流中,或者被流加载。

Properties虽然是Map体系的,但是没有泛型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package PropertiesDemo;

import java.util.Properties;
import java.util.Set;

public class Demo {
public static void main(String[] args) {
Properties prop = new Properties();

prop.put("1","孙健耕");
prop.put("2","王晓松");
prop.put("3","林青霞");

Set<Object> keyset = prop.keySet();
for (Object key: keyset){
Object value = prop.get(key);
System.out.println(key +","+ value);
}
}
}

321. Properties作为集合的特有方法

方法名 说明
Object setProperty(String key, String value) 设置集合的键和值,都是String类型,底层调用Hashtable方法put
String getProperty(String key) 使用此属性列表中指定的键搜索属性
Set<String> stringPropertyNames() 从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package PropertiesDemo;

import java.util.Properties;
import java.util.Set;

public class Demo2 {
public static void main(String[] args) {
Properties prop = new Properties();
prop.setProperty("123","孙健耕");
prop.setProperty("1234","孙健");

System.out.println(prop.getProperty("123"));
System.out.println(prop.getProperty("12343"));

Set<String> names = prop.stringPropertyNames();
for(String key: names){
System.out.println(key+","+prop.getProperty(key));
}
}
}

map那里的键值对原理是一样的。

322. Properties和IO流相结合

方法名 说明
void load(InputStream inStream) 从输入字节流读取属性列表(键和元素对)
void load(Reader reader) 从输入字符流读取属性列表(键和元素对)
void store(OutputStream out,String comments) 将此属性列表(键和元素对)写入此Properties表中,以适合于使用load(InputStream)方法的格式写入输出字节流
void store(Writer writer, String comments) 将此属性列表(键和元素对)写入此Properties表中,以适应使用load(Reader)方法的格式写入输出字符流。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package PropertiesDemo;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;

public class Demo3 {
public static void main(String[] args) throws IOException {
myStore();
myload();
}

private static void myload() throws IOException {
Properties prop = new Properties();
FileReader fr = new FileReader("java.txt");
prop.load(fr);
fr.close();
System.out.println(prop);
}


private static void myStore() throws IOException {
Properties prop = new Properties();

prop.setProperty("123","孙健耕");
prop.setProperty("1234","孙健");

FileWriter fw = new FileWriter("java.txt");
prop.store(fw,null);
fw.close();
}
}

把文件中的属性加载到集合。

323. 游戏次数

需求:用程序实现猜数字小游戏只能试玩三次,如果还想玩,提示想玩请充值。

思路:

  1. 写一个游戏类,里面有一个猜数字的小游戏。
  2. 写一个测试类。
1
2
#Sun Nov 21 22:29:49 CST 2021
count=3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package 游戏次数;

import java.util.Random;
import java.util.Scanner;

public class Game {
private Game(){};
public static void start(){
Random r = new Random();
int number = r.nextInt(100)+1;

while(true){
Scanner sc = new Scanner(System.in);
System.out.println("请输入你要猜的数字");
int guessNumber = sc.nextInt();

if(guessNumber > number){
System.out.println("你猜的数字"+guessNumber+"大了");
}else if(guessNumber<number){
System.out.println("你猜的数字"+guessNumber+"小了");
}else{
System.out.println("恭喜你猜中了");
break;
}
}
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package 游戏次数;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;

public class Demo {
public static void main(String[] args) throws IOException {

Properties prop = new Properties();

FileReader fr = new FileReader("idea_test\\java.txt");
prop.load(fr);
fr.close();

String count = prop.getProperty("count");
int number = Integer.parseInt(count);

if(number>=3){
System.out.println("请充值");
}else{
Game.start();
number++;
prop.setProperty("count",String.valueOf(number));
FileWriter fw = new FileWriter("idea_test\\java.txt");
prop.store(fw,null);
fw.close();

}

}
private static void myStore() throws IOException {
Properties prop = new Properties();
prop.setProperty("count","0");
FileWriter fw = new FileWriter("idea_test\\java.txt");
prop.store(fw,null);
fw.close();
}
}