JDK1.7 之java.nio.file.Files 讀取檔案只要一行
阿新 • • 發佈:2019-02-06
JDK1.7中引入了新的檔案操作類java.nio.file這個包,其中有個Files類它包含了很多有用的方法來操作檔案,比如檢查檔案是否為隱藏檔案,或者是檢查檔案是否為只讀檔案。開發者還可以使用Files.readAllBytes(Path)方法把整個檔案讀入記憶體,此方法返回一個位元組陣列,還可以把結果傳遞給String的構造器,以便建立字串輸出。此方法確保了當讀入檔案的所有位元組內容時,無論是否出現IO異常或其它的未檢查異常,資源都會關閉。這意味著在讀檔案到最後的塊內容後,無需關閉檔案。要注意,此方法不適合讀取很大的檔案,因為可能存在記憶體空間不足的問題。開發者還應該明確規定檔案的字元編碼,以避免任異常或解析錯誤。
讀取檔案只要一行
使用Java8 流的方式:
讀檔案一行寫檔案也只需要一行
readAllBytes(Path)方法的原始碼:
/**
* Reads all the bytes from a file. The method ensures that the file is
* closed when all bytes have been read or an I/O error, or other runtime
* exception, is thrown.
* 注意該方法只適用於簡單的情況,這種簡單的情況能夠很方便地將所有的位元組讀進一個位元組陣列,但並不適合用來讀取大檔案
* <p> Note that this method is intended for simple cases where it is
* convenient to read all bytes into a byte array. It is not intended for
* reading in large files.
*
* @param path
* the path to the file
*
* @return a byte array containing the bytes read from the file
*
* @throws IOException
* if an I/O error occurs reading from the stream
* 如果大於檔案2G,將丟擲記憶體溢位異常
* @throws OutOfMemoryError
* if an array of the required size cannot be allocated, for
* example the file is larger that {@code 2GB}
* @throws SecurityException
* In the case of the default provider, and a security manager is
* installed, the {@link SecurityManager#checkRead(String) checkRead}
* method is invoked to check read access to the file.
*/
public static byte[] readAllBytes(Path path) throws IOException {
try (SeekableByteChannel sbc = Files.newByteChannel(path);
InputStream in = Channels.newInputStream(sbc)) {//JDK1.7 try-with-resource
long size = sbc.size();
if (size > (long)MAX_BUFFER_SIZE)
throw new OutOfMemoryError("Required array size too large");
return read(in, (int)size);
}
}
讀取檔案只要一行
package entryNIO;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class BufferAndChannel {
public static void main(String[] args) {
try {
System.out.println(
new String(Files.readAllBytes(Paths.get("C:\\FileChannelImpl.java")))
);
} catch (IOException e) {
e.printStackTrace();
}
}
}
readAllLines方法的原始碼
public static List<String> readAllLines(Path path, Charset cs) throws IOException {
try (BufferedReader reader = newBufferedReader(path, cs)) {
List<String> result = new ArrayList<>();
for (;;) {
String line = reader.readLine();
if (line == null)
break;
result.add(line);
}
return result;
}
}
package entryNIO;
import java.util.List;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
public class BufferAndChannel {
public static void main(String[] args) {
//如果是文字檔案也可以這麼讀 呼叫readAllLines 方法
try {//JDK1.8以後可以省略第二個引數,預設是UTF-8編碼
List<String> lines = Files.readAllLines(Paths.get("C:\\FileChannelImpl.java"), StandardCharsets.UTF_8);
StringBuilder sb = new StringBuilder();
for (String line : lines) {
sb.append(line+"\n");// \r\n 換行符
}
String fromFile = sb.toString();
System.out.println(fromFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用Java8 流的方式:
先看原始碼實現
public static Stream<String> lines(Path path) throws IOException {
return lines(path, StandardCharsets.UTF_8);
}
package entryNIO;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class BufferAndChannel {
public static void main(String[] args) {
//Java8 新增lines方法
try {
// Java8用流的方式讀檔案,更加高效
Files.lines(Paths.get("C:\\FileChannelImpl.java")).forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
}
讀檔案一行寫檔案也只需要一行
package entryNIO;
import java.util.Arrays;
import java.util.List;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
public class BufferAndChannel {
public static void main(String[] args){
//Java8 新增lines方法
String filePath="C:\\FileChannelImpl.java";
try {
// Java8用流的方式讀檔案,更加高效
/*Files.lines(Paths.get(filePath)).forEach((line)->{
try {
Files.write(Paths.get("\\1.java"), line.getBytes(), StandardOpenOption.APPEND);
//Files.copy(in, target, options);
} catch (IOException e) {
e.printStackTrace();
}
}); */
/* Files.readAllLines(Path path)方法返回值為List<String>型別,就是為Files.write()而設計的
* 因為Files.write()需要傳入一個Iterable<? extends CharSequence>型別的引數
*
* Files.write(Path path, Iterable<? extends CharSequence> lines, OpenOption... options)
*/
List<String> stringStream=Files.readAllLines(Paths.get(filePath));
//因為Files.lines(Path path)返回的是Stream<String>,所以可以通過下面這種方法變成List<String>
//List<String> stringStream2=Arrays.asList((String[])Files.lines(Paths.get(filePath)).toArray());
//StandardOpenOption為列舉類 ,如果當前所Paths.get()的檔案不存在,第三個引數可選擇StandardOpenOption.CREATE_NEW
//檔案存在則拋java.nio.file.FileAlreadyExistsException異常
Files.write(Paths.get("C:\\2.java"), stringStream, StandardOpenOption.CREATE_NEW);
} catch (IOException e) {
e.printStackTrace();
}
}
}