文件轉字符串方式 --- (環繞執行模式&行爲參數化&函數式接口|Lambda表達式)
嗯,當然論方便的話,我們直接可以使用,
org.apache.commons.io.FileUtils;
String readFileToString(final File file, final String encoding)
這裏緊作爲一種思路學習
首先我們講幾個概念:
-
環繞執行模式:
- 簡單的講,就是對於OI,JDBC等類似資源,在用完之後需要關閉的,資源處理時常見的一個模式是打開一個資源,做一些處理,然後關閉資源,這個設置和清理階段類似,並且會圍繞着執行處理的業務邏輯。這就是環繞執行模式。
-
行爲參數化:
- 函數式編程的一種思想,通過把代碼包裝爲參數傳遞行爲,即把代碼邏輯包裝爲一個參數,傳到方法裏。
-
Lambda表達式:
- Lambda表達式理解爲簡潔的表示可傳遞的匿名函數的一種方式,它沒有名稱,但它有函數體,參數列表,返回類型。可以拋出一個異常類型。包裝代碼邏輯爲參數即使用Lambda表達式。
-
函數式接口:
- 本質上是隻有一個抽象方法的普通接口,可以被隱式的轉換爲Lambda表達式,需要用註解定義(@FunctionalInterface)。默認方法和靜態方法可以不屬於抽象方法,可以在函數式接口中定義。
- 如果函數式接口中額外定義多個抽象方法,那麼這些抽象方法簽名必須和Object的public方法一樣,接口最終有確定的類實現, 而類的最終父類是Object。 因此函數式接口可以定義Object的public方法。
-
@FunctionalInterfacepublic interface ObjectMethodFunctionalInterface { void count(int i); String toString(); //same to Object.toString int hashCode(); //same to Object.hashCode boolean equals(Object obj); //same to Object.equals }
-
關於更多的java8學習,
- 《Java8實戰》個人感覺這本書不錯。也可以看看我的博客,《java8實戰》讀書筆記,裏面有這本書的PDF資源
下面我們先看一個簡單的環繞執行模式:
1)第一步;當需要更改邏輯代碼是,需要重寫代碼,所以想到行爲參數化
public static String processFile()throws IOException {
try(BufferedReader bufferedReader =
new BufferedReader(new FileReader("data.txt"))){
// return bufferedReader.readLine();
return bufferedReader.readLine()+bufferedReader.readLine();
}
2)第二步,使用函數式接口來傳遞一個行爲
@FunctionalInterface
public interface BufferReaderProcessFile{
// 方法簽名爲 BufferReader -> String
String peocess(BufferedReader bufferedReader)throws IOException;
}
3)第三步,執一個行爲,任何BufferReader -> String的Lambda表達式都可以作爲參數傳入。只要符合peocess方法的簽名即可。
public static String processFiles(BufferReaderProcessFile bufferReaderProcessFile)throws IOException {
try(BufferedReader bufferedReader =
new BufferedReader(new FileReader("data.txt"))){
return bufferReaderProcessFile.peocess(bufferedReader) ;
4)第四步,傳遞Lambda
String string = processFiles((BufferedReader bs) ->bs.readLine());
文件轉換爲字符串
我的思路,我對java IO用的不是很熟,大家有好的方法請留言,相互學習:
- FileInputStream fileInputStream = new FileInputStream(file))
- InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream))
- BufferedReader bufferedReader = new BufferedReader(inputStreamReader))
- String str = bufferedReader.readLine()
- 字節流-》字符流-》字符緩存流 即 將字節流轉換爲字符流之後在用高級流包裝。
所以我的思路是避免在邏輯裏出現太多的IO流關閉,和異常捕獲,專心處理讀取邏輯即可,結合以下兩種技術:
- try(){}【自動關閉流,1.7支持】
- lambda特性來實現【行爲參數化,1.8】
步驟:
函數式接口傳遞行爲的定義:
package com.liruilong.demotext.service.utils.interfaceutils;
import java.io.BufferedReader;
import java.io.IOException;
/**
* @Description : 函數接口,描述BufferedReader ->String的轉化方式
* @Author: Liruilong
* @Date: 2020/3/17 15:44
*/
@FunctionalInterface
public interface InputStreamPeocess {
/**
* @Author Liruilong
* @Description 方法簽名 BufferedReader ->String
* @Date 15:47 2020/3/17
* @Param [inputStream]
* @return com.liruilong.demotext.service.utils.InputStream
**/
String peocess(BufferedReader bufferedReader) throws IOException;
}
執一個行爲,任何BufferReader -> String的Lambda表達式都可以作爲參數傳入。只要符合peocess方法的簽名即可。
/**
* @return java.lang.String
* @Author Liruilong
* @Description 環繞處理
* @Date 17:14 2020/3/17
* @Param [inputStreamPeocess, file]
**/
public static String fileToBufferedReader(InputStreamPeocess inputStreamPeocess, File file) {
try (FileInputStream fileInputStream = new FileInputStream(file)) {
try (InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream)) {
try (BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {
return inputStreamPeocess.peocess(bufferedReader);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
return null;
}
}
執行Lambda
/**
* @return java.lang.String
* @Author Liruilong
* @Description 文件轉字符串
* @Date 17:22 2020/3/17
* @Param [file]
**/
public static String readJsonToString(File file) {
return string = fileToBufferedReader((bufferedReader) -> {
String str = null;
StringBuilder stringBuilder = new StringBuilder();
while ((str = bufferedReader.readLine()) != null) {
stringBuilder.append(str);
}
return stringBuilder.toString();
}, file);
}
這樣好處:
- 我們只需要關心具體的讀取邏輯即可,不需要關心其他,
- 可以用於文本處理,對讀取的字符串進行過濾等操作。
不足之處希望小夥伴批評指教。生活加油..