Java 文件练习(名单)

OOP h14

现在所有学生的名单 students.txt(为了避免乱码问题,文件中不包含汉字),其中每行为一个学生信息,包括学号、姓名、班级,以 tab 符号分割(\t)。

学院要求所有同学把自己一寸照片发给辅导员,图片命名规则为 “学号.jpg”

现在存在下列问题,请用编程的方式帮助辅导员解决如下问题:

  1. 找出哪些同学没有交照片;
  2. 在目标目录下每个班级建立一个子目录,把上交的同学的照片,统一按 学号_姓名.jpg 方式拷贝到各自班级目录下,原来的文件不要删除。

实际测试中,文件存放位置可能改变,学生数量也可能改变。

txt 文件给出了学生名单,某文件夹下是学生上交的图片。

首先读取 txt 文件,每行为一个字符串数组,所有行组成一个列表;读取文件夹,获得有效的文件名,组成字符串列表,然后进一步判断。

0x00 getNameList

按行读取 txt 文件,按 \t 分隔,按格式存储信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public List<String[]> getNameList(String filename) throws IOException {
String line = "";
Reader reader;
List<String[]> result = new ArrayList<>();
reader = new FileReader(filename);
LineNumberReader lineReader = new LineNumberReader(reader);
while (true) {
line = lineReader.readLine();
if (line == null) {
break;
}
result.add(line.split("\t"));
}
return result;
}

0x01 getValidFileIdList

获取文件夹下有效的文件名(学号)列表。

传入参数为目录,用 listFiles 列出目录下的所有文件,然后遍历这些文件,取文件名,若符合学号的标准则存储,最终返回。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
	public List<String> getValidFileIdList(String filename) throws FileNotFoundException {
List<String> result = new ArrayList<>();
File file = new File(filename);
File[] fileList = file.listFiles();
if (fileList == null) {
throw new FileNotFoundException();
}
for (File fileEle : fileList) {
String name = fileEle.getName();
if (name.matches("[0-9]{10}.jpg")) {
result.add(name.substring(0, 10));
}
}
return result;
}

0x02 copyFile

拷贝文件方法。

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
/**
* 复制IO流
*
* @param in
* @param out
* @throws IOException
*/
public static void copyIO(InputStream in, OutputStream out)
throws IOException {
byte[] buf = new byte[CHUNK_SIZE];
/**
* 从输入流读取内容并写入到另外一个流的典型方法
*/
int len = in.read(buf);
while (len != -1) {
out.write(buf, 0, len);
len = in.read(buf);
}
}

/**
* 复制文件
*
* @param fsrc
* @param fdest
* @throws IOException
*/
public static void copyFile(String fsrc, String fdest) throws IOException {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(fsrc);
out = new FileOutputStream(fdest, true);
copyIO(in, out);
} finally {
close(in);
close(out);
}
}

/**
* 关闭一个输入 输出流
*
* @param inout
*/
public static void close(Closeable inout) {
if (inout != null) {
try {
inout.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

0x03 copyToTargetDirAndReturnNoExist

找到未交照片的学生,并将已交照片拷贝至指定目录且重命名。

由于拷贝的目标目录下还需建立班级子目录,所以可以遍历名单,若对应的班级文件夹不存在则创建。

遍历名单,若对应的学号在已交文件名列表中不存在,则将其姓名加入未交照片列表,否则拷贝其对应的文件。

注意文件的扩展名以及目录的斜杠等细节。

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
public Set<String> copyToTargetDirAndReturnNoExist(String studentListFile,String srcDir,String target) throws Exception {
List<String[]> nameList = getNameList(studentListFile);
List<String> fileIdList = getValidFileIdList(srcDir);
Set<String> noExistIdSet = new HashSet<>();

for (String[] stu : nameList) {
File targetDir = new File(target, stu[2]);
if (!targetDir.exists()) {
targetDir.mkdirs();
}
}
int i;
for (i = 0; i < nameList.size(); i++) {
String id = nameList.get(i)[0];
String name = nameList.get(i)[1];
String classNo = nameList.get(i)[2];

if (!fileIdList.contains(id)) {
noExistIdSet.add(id);
} else {
String srcPath = srcDir + id + ".jpg";
String targetPath = target + classNo + "/" + id + "_" + name + ".jpg";
copyFile(srcPath, targetPath);
}
}
return noExistIdSet;
}

0x04 完整代码

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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package com.huawei.classroom.student.h14;

import java.io.*;
import java.util.*;
/**
* 在本包下增加合适的类和方法, 本程序不但要测试通过,还需要写适当的注释
*
* 不要引用jdk1.8以外第三方的包
*
* @author super
*
*/
public class MyTools {
public static int CHUNK_SIZE = 4096;

public MyTools( ) {
// TODO Auto-generated constructor stub
}

/**
*
* @param studentListFile 存放学生名单的文件名
* @param srcDir 图片存放的目录(不会包含子目录)
*/
public Set<String> copyToTargetDirAndReturnNoExist(String studentListFile,String srcDir,String target) throws Exception {
List<String[]> nameList = getNameList(studentListFile);
List<String> fileIdList = getValidFileIdList(srcDir);
Set<String> noExistIdSet = new HashSet<>();

for (String[] stu : nameList) {
File targetDir = new File(target, stu[2]);
if (!targetDir.exists()) {
targetDir.mkdirs();
}
}
int i;
for (i = 0; i < nameList.size(); i++) {
String id = nameList.get(i)[0];
String name = nameList.get(i)[1];
String classNo = nameList.get(i)[2];

if (!fileIdList.contains(id)) {
noExistIdSet.add(id);
} else {
String srcPath = srcDir + id + ".jpg";
String targetPath = target + classNo + "/" + id + "_" + name + ".jpg";
copyFile(srcPath, targetPath);
}
}
return noExistIdSet;
}

/**
* @param filename
* @return
* @throws FileNotFoundException
*/
public List<String> getValidFileIdList(String filename) throws FileNotFoundException {
List<String> result = new ArrayList<>();
File file = new File(filename);
File[] fileList = file.listFiles();
if (fileList == null) {
throw new FileNotFoundException();
}
for (File fileEle : fileList) {
String name = fileEle.getName();
if (name.matches("[0-9]{10}.jpg")) {
result.add(name.substring(0, 10));
}
}
return result;
}

/**
* @param filename
* @return
* @throws IOException
*/
public List<String[]> getNameList(String filename) throws IOException {
String line = "";
Reader reader;
List<String[]> result = new ArrayList<>();
reader = new FileReader(filename);
LineNumberReader lineReader = new LineNumberReader(reader);
while (true) {
line = lineReader.readLine();
if (line == null) {
break;
}
result.add(line.split("\t"));
}
return result;
}

/**
* 复制IO流
*
* @param in
* @param out
* @throws IOException
*/
public static void copyIO(InputStream in, OutputStream out)
throws IOException {
byte[] buf = new byte[CHUNK_SIZE];
/**
* 从输入流读取内容并写入到另外一个流的典型方法
*/
int len = in.read(buf);
while (len != -1) {
out.write(buf, 0, len);
len = in.read(buf);
}
}

/**
* 复制文件
*
* @param fsrc
* @param fdest
* @throws IOException
*/
public static void copyFile(String fsrc, String fdest) throws IOException {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(fsrc);
out = new FileOutputStream(fdest, true);
copyIO(in, out);
} finally {
close(in);
close(out);
}
}

/**
* 关闭一个输入 输出流
*
* @param inout
*/
public static void close(Closeable inout) {
if (inout != null) {
try {
inout.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}