菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
172
0

文件转换为字符串如何优雅的实现(环绕执行模式&行为参数化&函数式接口|Lambda表达式)

原创
05/13 14:22
阅读数 88711

 

文件转字符串方式  ---  (环绕执行模式&行为参数化&函数式接口|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方法。
  • 关于更多的java8学习,《Java8实战》个人感觉这本书不错。也可以看看我的博客,《java8实战》读书笔记,里面有这本书的PDF资源
@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
}  

 

下面我们先看一个简单的环绕执行模式:

 

第一步;当需要更改逻辑代码是,需要重写代码,所以想到行为参数化

public static String processFile()throws IOException {
        try(BufferedReader bufferedReader =
                new BufferedReader(new FileReader("data.txt"))){
           // return  bufferedReader.readLine();
            return  bufferedReader.readLine()+bufferedReader.readLine();
        }

 

第二步,使用函数式接口来传递一个行为

@FunctionalInterface
    public  interface BufferReaderProcessFile{
        // 方法签名为 BufferReader -> String
        String peocess(BufferedReader bufferedReader)throws IOException;
    }

 

第三步,执一个行为,任何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) ;

 

第四步,传递Lambda

String string = processFiles((BufferedReader bs) ->bs.readLine());

 

 

 

 

 

文件转换为字符串,我的思路,我对java IO用的不是很熟,大家有好的方法请留言,相互学习

  1. FileInputStream fileInputStream = new FileInputStream(file))
  2. InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream))
  3. BufferedReader bufferedReader = new BufferedReader(inputStreamReader))
  4. String str = bufferedReader.readLine()
  5. 字节流-》字符流-》字符缓存流 即 将字节流转换为字符流之后在用高级流包装。

所以我的思路是避免在逻辑里出现太多的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);
    }

为了美观,我把异常抛了出去,这样好处:

  • 我们只需要关心具体的读取逻辑即可,不需要关心其他,
  • 可以用于文本处理,对读取的字符串进行过滤等操作。

不足之处希望小伙伴批评指教。生活加油..

 

发表评论

0/200
172 点赞
0 评论
收藏
为你推荐 换一批