# 问题和练习 : 基本I/O
# 问题
你将用什么类和方法来读取位于大文件末端附近已知位置的几条数据?
在调用 forma t时,指示新行的最佳方式是什么?
如何确定文件的 MIME 类型?
您将用什么方法来确定文件是否是符号链接?
# 答案
- Files.newByteChannel 返回一个实例 SeekableByteChannel,允许您从(或写入)文件中的任何位置读取。 随机访问文件
- 使用
%n
参数 而不是\n
格式化 Files.probeContentType
方法使用平台的底层文件类型检测器来评估和返回 MIME 类型。 其他有用的方法Files.isSymbolicLink
方法。 符号链接或其他
# 练习
# 练习 1
编写一个例子来计算特定字符(例如 e)出现在文件中的次数。字符可以在命令行中指定。您可以使用 xanadu.txt 输入文件。
public class CountLetter {
private char lookFor; //需要统计的目标字符
private Path file; // 需要在该文件中查找文件
public CountLetter(char lookFor, Path file) {
this.lookFor = lookFor;
this.file = file;
}
/** 开始统计 */
public int count() {
int count = 0;
try {
BufferedReader reader = Files.newBufferedReader(file, Charset.forName("utf-8"));
String line = null;
while ((line = reader.readLine()) != null) {
for (int i = 0; i < line.length(); i++) {
if (lookFor == line.charAt(i)) {
count++;
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
return count;
}
static void usage() {
System.out.println("usage: java CountLetter <letter>");
System.exit(-1);
}
public static void main(String[] args) {
// 在idea中模拟命令行,输入参数
args = new String[]{"e"};
if (args.length != 1 || args[0].length() != 1) {
usage();
}
char lookFor = args[0].charAt(0);
Path file = Paths.get("d20170313-jdk-sources-code/src/test/resources/xanadu.txt");
System.out.println(file.toAbsolutePath());
int count = new CountLetter(lookFor, file).count();
System.out.format("字符 '%c',在文件 '%s' 中出现了 %d 次.%n", lookFor, file, count);
}
}
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
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
# 练习2.
文件 datafile 以一个单一的方式开始 long,告诉您 int 同一文件中单个数据的偏移量。 编写一个获取 int 数据的程序。什么是 int 数据?
官方 datafile 文件链接已经 404 了,所以下面这断代码是标识啥意思。我没有看明白,直接忽略跳过该练习
public class FindInt {
private Path file;
FindInt(Path file) {
this.file = file;
}
public int seek() throws IOException {
int num = -1;
try (SeekableByteChannel fc = Files.newByteChannel(file)) {
ByteBuffer buf = ByteBuffer.allocate(8);
//Get the offset into the file.
fc.read(buf);
long offset = buf.getLong(0);
//Seek to the offset location.
fc.position(offset);
buf.rewind();
//Read the 'secret' value.
fc.read(buf);
num = buf.getInt(0);
} catch (IOException x) {
System.err.println(x);
}
return num;
}
public static void main(String[] args) throws IOException {
Path file = Paths.get("datafile");
int num = new FindInt(file).seek();
System.out.println("The value is " + num);
}
}
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
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