回答編集履歴

1

コメントに対する回答を追加

2020/10/02 14:39

投稿

kazuma-s
kazuma-s

スコア8224

test CHANGED
@@ -47,3 +47,111 @@
47
47
  }
48
48
 
49
49
  ```
50
+
51
+ **追記**
52
+
53
+ > close(); を一度使うと二度と Scanner を使えなくなるという認識で正しいでしょうか。
54
+
55
+
56
+
57
+ System.in に関してはそうです。
58
+
59
+ 他のファイルや文字列に対しては、Scanner は何度でも使えます。
60
+
61
+
62
+
63
+ System.in に関しても close() しなければ何度でも使えますが、
64
+
65
+ new するたびにバッファが確保され、リソースが無駄になります。
66
+
67
+
68
+
69
+ まず、次のコードを試してみてください。
70
+
71
+ ```Java
72
+
73
+ import java.util.Scanner;
74
+
75
+
76
+
77
+ class Test {
78
+
79
+ public static void main(String[] args) {
80
+
81
+ Scanner sc = new Scanner(System.in);
82
+
83
+ if (!sc.hasNextLine()) {
84
+
85
+ System.out.println("1. no line");
86
+
87
+ return;
88
+
89
+ }
90
+
91
+ String line = sc.nextLine();
92
+
93
+ System.out.println(line);
94
+
95
+ sc.close();
96
+
97
+
98
+
99
+ sc = new Scanner(System.in);
100
+
101
+ if (!sc.hasNextLine()) {
102
+
103
+ System.out.println("2. no line");
104
+
105
+ return;
106
+
107
+ }
108
+
109
+ line = sc.nextLine();
110
+
111
+ System.out.println(line);
112
+
113
+ sc.close();
114
+
115
+ }
116
+
117
+ }
118
+
119
+ ```
120
+
121
+ 2回目の new Scanner(System.in); はエラーになります。
122
+
123
+
124
+
125
+ では、最初の sc.close(); を実行しなければどうなるか?
126
+
127
+ キーボード入力で 2行読めます。
128
+
129
+
130
+
131
+ ところが、java Test <file.txt のように標準入力をファイルに切り替えると
132
+
133
+ 2行目の読み込みができません。
134
+
135
+
136
+
137
+ なぜかというと、Scanner は内部にバッファ(多分 8KB)を用意します。
138
+
139
+
140
+
141
+ 入力がキーボードだと、1回の read で、1行しかバッファに読み込まないため、
142
+
143
+ 新しい Scanner でも次の行が読めます。
144
+
145
+
146
+
147
+ でも、入力がファイルだと、最初の Scanner がファイルを読み込めるだけ全部
148
+
149
+ バッファに読み込んでしまいます。
150
+
151
+ 次の Scanner はもう読み込むものがありません。
152
+
153
+ ファイルのサイズが 8KB 以上だったら、続きが読めます。
154
+
155
+ でも、2行目は最初の Scanner で読み込まれているので、
156
+
157
+ ずっと後の行の途中からしか読み込めません。