Tất cả các câu trả lời cho đến nay đều liên quan đến việc đọc từng dòng của tệp, lấy dòng đó làm a String
, và sau đó xử lý String
.
Không nghi ngờ gì rằng đây là cách tiếp cận dễ hiểu nhất và nếu tệp khá ngắn (hàng chục nghìn dòng), nó cũng sẽ được chấp nhận về mặt hiệu quả. Nhưng nếu tệp dài , thì đó là một cách rất kém hiệu quả để làm điều đó, vì hai lý do:
- Mỗi ký tự được xử lý hai lần, một lần khi xây dựng
String
và một lần khi xử lý nó.
- Trình thu gom rác sẽ không phải là bạn của bạn nếu có nhiều dòng trong tệp. Bạn đang tạo một cái mới
String
cho mỗi dòng, và sau đó vứt nó đi khi bạn chuyển sang dòng tiếp theo. Người thu gom rác cuối cùng sẽ phải vứt bỏ tất cả những String
đồ vật mà bạn không muốn nữa. Ai đó phải dọn dẹp sau bạn.
Nếu bạn quan tâm đến tốc độ, bạn nên đọc một khối dữ liệu và sau đó xử lý nó theo từng byte thay vì từng dòng một. Mỗi khi bạn đến cuối một số, bạn thêm nó vào số List
bạn đang xây dựng.
Nó sẽ xuất hiện một cái gì đó như thế này:
private List<Integer> readIntegers(File file) throws IOException {
List<Integer> result = new ArrayList<>();
RandomAccessFile raf = new RandomAccessFile(file, "r");
byte buf[] = new byte[16 * 1024];
final FileChannel ch = raf.getChannel();
int fileLength = (int) ch.size();
final MappedByteBuffer mb = ch.map(FileChannel.MapMode.READ_ONLY, 0,
fileLength);
int acc = 0;
while (mb.hasRemaining()) {
int len = Math.min(mb.remaining(), buf.length);
mb.get(buf, 0, len);
for (int i = 0; i < len; i++)
if ((buf[i] >= 48) && (buf[i] <= 57))
acc = acc * 10 + buf[i] - 48;
else {
result.add(acc);
acc = 0;
}
}
ch.close();
raf.close();
return result;
}
Đoạn mã trên giả định rằng đây là ASCII (mặc dù nó có thể được điều chỉnh dễ dàng cho các mã hóa khác) và bất kỳ thứ gì không phải là chữ số (cụ thể là dấu cách hoặc dòng mới) đại diện cho ranh giới giữa các chữ số. Nó cũng giả định rằng tệp kết thúc bằng một chữ số không (trong thực tế, dòng cuối cùng kết thúc bằng một dòng mới), tuy nhiên, một lần nữa, nó có thể được điều chỉnh để đối phó với trường hợp không.
Nó nhanh hơn nhiều so với bất kỳ String
cách tiếp cận dựa trên cơ sở nào cũng được đưa ra như câu trả lời cho câu hỏi này. Có một cuộc điều tra chi tiết về một vấn đề rất giống trong câu hỏi này . Bạn sẽ thấy ở đó có khả năng cải thiện nó hơn nữa nếu bạn muốn đi xuống dòng đa luồng.