อ่านข้อความทั้งหมดจากไฟล์
Java 11 เพิ่มเมธอด readString ()เพื่ออ่านไฟล์ขนาดเล็กเป็น a String
, รักษาตัววางสาย:
String content = Files.readString(path, StandardCharsets.US_ASCII);
สำหรับรุ่นระหว่าง Java 7 และ 11 ต่อไปนี้เป็นสำนวนที่กะทัดรัดและทนทานซึ่งรวมอยู่ในวิธีการยูทิลิตี้:
static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
อ่านบรรทัดของข้อความจากไฟล์
Java 7 เพิ่มวิธีการสะดวกในการอ่านไฟล์เป็นบรรทัดของข้อความที่List<String>
แสดงเป็น วิธีนี้คือ "lossy" เนื่องจากตัวแยกบรรทัดถูกแยกออกจากส่วนท้ายของแต่ละบรรทัด
List<String> lines = Files.readAllLines(Paths.get(path), encoding);
Java 8 เพิ่มวิธีการในการผลิตFiles.lines()
Stream<String>
อีกครั้งวิธีนี้จะสูญเสียเนื่องจากตัวแยกบรรทัดถูกปล้น หากIOException
พบว่ามีในขณะที่อ่านไฟล์มันจะถูกห่อในUncheckedIOException
เนื่องจากStream
ไม่ยอมรับ lambdas ที่โยนข้อยกเว้นที่ตรวจสอบแล้ว
try (Stream<String> lines = Files.lines(path, encoding)) {
lines.forEach(System.out::println);
}
นี้Stream
ไม่จำเป็นต้องclose()
โทร; นี่เป็นเอกสารที่ไม่ดีบน API และฉันสงสัยว่าหลายคนไม่ได้สังเกตเห็นว่าStream
มีclose()
วิธี ต้องแน่ใจว่าใช้ ARM-block ดังที่แสดง
หากคุณทำงานกับแหล่งข้อมูลอื่นนอกเหนือจากไฟล์คุณสามารถใช้lines()
วิธีการBufferedReader
แทน
การใช้งานหน่วยความจำ
วิธีแรกที่เก็บรักษาตัวแบ่งบรรทัดอาจต้องใช้หน่วยความจำชั่วคราวหลายครั้งขนาดของไฟล์เพราะในช่วงเวลาสั้น ๆ เนื้อหาไฟล์ดิบ (อาร์เรย์ไบต์) และตัวถอดรหัส (แต่ละที่เป็น 16 บิตแม้ว่าการเข้ารหัส เป็น 8 บิตในไฟล์) อยู่ในหน่วยความจำพร้อมกัน จะปลอดภัยที่สุดที่จะใช้กับไฟล์ที่คุณรู้ว่ามีขนาดเล็กเมื่อเทียบกับหน่วยความจำที่มีอยู่
วิธีที่สองบรรทัดการอ่านมักจะมีหน่วยความจำมีประสิทธิภาพมากขึ้นเนื่องจากบัฟเฟอร์ไบต์อินพุตสำหรับการถอดรหัสไม่จำเป็นต้องมีไฟล์ทั้งหมด อย่างไรก็ตามยังคงไม่เหมาะสำหรับไฟล์ที่มีขนาดใหญ่มากเมื่อเทียบกับหน่วยความจำที่มีอยู่
สำหรับการอ่านไฟล์ขนาดใหญ่คุณต้องมีการออกแบบที่แตกต่างกันสำหรับโปรแกรมของคุณหนึ่งไฟล์ที่อ่านข้อความจำนวนมากจากสตรีมประมวลผลจากนั้นย้ายไปยังส่วนต่อไปแล้วนำบล็อกหน่วยความจำขนาดคงที่มาใช้ซ้ำ ที่นี่ "ใหญ่" ขึ้นอยู่กับรายละเอียดของคอมพิวเตอร์ ทุกวันนี้เกณฑ์นี้อาจมี RAM หลายกิกะไบต์ วิธีที่สามการใช้ a Stream<String>
เป็นวิธีหนึ่งในการทำเช่นนี้หากอินพุต "บันทึก" ของคุณเกิดขึ้นเป็นแต่ละบรรทัด (การใช้readLine()
วิธีการBufferedReader
เป็นขั้นตอนที่เทียบเท่ากับวิธีการนี้)
การเข้ารหัสอักขระ
สิ่งหนึ่งที่ขาดหายไปจากตัวอย่างในโพสต์ต้นฉบับคือการเข้ารหัสอักขระ มีกรณีพิเศษบางอย่างที่ค่าเริ่มต้นของแพลตฟอร์มเป็นสิ่งที่คุณต้องการ แต่เป็นกรณีที่หายากและคุณควรจะสามารถพิสูจน์ตัวเลือกของคุณได้
StandardCharsets
ระดับกำหนดค่าคงที่บางอย่างสำหรับการเข้ารหัสที่จำเป็นทั้งหมด runtimes Java:
String content = readFile("test.txt", StandardCharsets.UTF_8);
เริ่มต้นแพลตฟอร์มสามารถใช้ได้จากระดับตัวเอง:Charset
String content = readFile("test.txt", Charset.defaultCharset());
หมายเหตุ: คำตอบนี้ส่วนใหญ่จะแทนที่รุ่น Java 6 ของฉัน ยูทิลิตี้ของ Java 7 ทำให้รหัสง่ายขึ้นอย่างปลอดภัยและคำตอบเก่าซึ่งใช้บัฟเฟอร์ไบต์ที่แมปป้องกันไฟล์ที่ถูกอ่านจากการถูกลบจนกว่าบัฟเฟอร์ที่แมปจะถูกเก็บรวบรวมขยะ คุณสามารถดูเวอร์ชั่นเก่าผ่านลิงค์ "แก้ไข" ในคำตอบนี้