Java OutputStream 读取字符串行

2024-04-27

我使用一个 API(更多信息,见下文),它接受输出流捕获数据。相反,我想提供一个Consumer of Strings它消耗了一行又一行的数据。因此我必须编写一个 OutputStream 实现来包装这样的 Consumer。这是我能想到的最简单的:

import java.io.OutputStream;
import java.util.Objects;
import java.util.function.Consumer;

public class OutputStreamConsumer extends OutputStream {

    private final Consumer<String> consumer;
    private final StringBuilder sb = new StringBuilder();

    public OutputStreamConsumer(Consumer<String> consumer) {
        this.consumer = Objects.requireNonNull(consumer);
    }

    @Override
    public void write(int b) {
        char c = (char) b;
        if (c == '\r') {
            return;
        }
        if (c == '\n') {
            consume();
            return;
        }
        this.sb.append(c);
    }

    @Override
    public void close() {
        if (sb.length() != 0) {
            consume();
        }
    }

    private void consume() {
        this.consumer.accept(this.sb.toString());
        this.sb.delete(0, Integer.MAX_VALUE);
    }

}

然而,这对于生产代码来说可能还不够encoding and 表现。我认为必要的逻辑已经包含在输入流读取器 and 缓冲读取器但在这种情况下我不能使用这些类。 编写这种OutputStream的最佳方法是什么?我可以使用哪些 jdk 类来避免编写一堆处理编码、行尾等的低级代码。

具体用例

在 Gradle 插件项目中,我使用 Gradle 的项目 API 启动外部进程:ExecSpec https://docs.gradle.org/current/javadoc/org/gradle/process/ExecSpec.html。我可以使用以下方法设置 OutputStreams设置标准输出 and 设置错误输出为了捕获该过程的输出。


由于到目前为止还没有答案,我将在撰写本文时发布我的“最佳”解决方案。欢迎发布更好的解决方案。

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Objects;
import java.util.function.Consumer;

public class LineReadingOutputStream extends OutputStream {

    private static final byte CR = '\r';
    private static final byte LF = '\n';

    private final Consumer<String> consumer;
    private final StringBuilder stringBuilder = new StringBuilder();
    private boolean lastCR = false;

    private LineReadingOutputStream(final Consumer<String> consumer) {
        this.consumer = Objects.requireNonNull(consumer);
    }

    @Override
    public void write(final int b) throws IOException {
        write(new byte[]{(byte) b});
    }

    @Override
    public void write(final byte[] b, int start, final int len) {
        if (b == null) {
            throw new NullPointerException();
        }
        if (len < 0) {
            throw new IllegalArgumentException();
        }
        final int end = start + len;
        if ((start < 0) || (start > b.length) || (end < 0) || (end > b.length)) {
            throw new IndexOutOfBoundsException();
        }

        if (this.lastCR && start < end && b[start] == LF) {
            start++;
            this.lastCR = false;
        } else if (start < end) {
            this.lastCR = b[end - 1] == CR;
        }

        int base = start;
        for (int i = start; i < end; i++) {
            if (b[i] == LF || b[i] == CR) {
                final String chunk = asString(b, base, i);
                this.stringBuilder.append(chunk);
                consume();
            }
            if (b[i] == LF) {
                base = i + 1;
            } else if (b[i] == CR) {
                if (i < end - 1 && b[i + 1] == LF) {
                    base = i + 2;
                    i++;
                } else {
                    base = i + 1;
                }
            }
        }
        final String chunk = asString(b, base, end);
        this.stringBuilder.append(chunk);
    }

    @Override
    public void close() {
        if (this.stringBuilder.length() != 0) {
            consume();
        }
    }

    private static String asString(final byte[] b, final int start, final int end) {
        if (start > end) {
            throw new IllegalArgumentException();
        }
        if (start == end) {
            return "";
        }
        final byte[] copy = Arrays.copyOfRange(b, start, end);
        return new String(copy, StandardCharsets.UTF_8);
    }

    private void consume() {
        this.consumer.accept(this.stringBuilder.toString());
        this.stringBuilder.delete(0, Integer.MAX_VALUE);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java OutputStream 读取字符串行 的相关文章

  • Android PhoneGap 插件,UI 选项卡栏,调整 WebView 大小

    我正在创建一个美味的 PhoneGap 插件 希望一旦它能被打开 准备好了 插件基本完成了 我只需要一个漂亮的用户界面 相互作用 简而言之 我想创建一个 本机 android 工具栏组件 如果您实现 PhoneGap UIControls
  • 在哪里可以获得有关 Java FitNesse 和 Slim 的一些教程? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何开始使用 Chainsaw for Log4j?

    我想开始使用 Chainsaw v2 几乎没有关于它的信息 我只找到了this http www velocityreviews com forums t140105 help using chainsaw for log4j html 但
  • 无法使用 json 架构验证器根据预定义的 yaml 文件验证查询参数

    我需要根据预定义的 yaml 文件架构验证查询参数的架构 因此我使用 json 架构验证器 验证如何失败 我正在执行以下步骤 填充参数和相应的架构 final List
  • Junit maven构建错误(maven-surefire-plugin:2.19.1:测试失败:分叉进程中出现错误)[重复]

    这个问题在这里已经有答案了 我通过引用创建了一个示例 struts 2 项目和 J unit 测试用例link http self learning java tutorial blogspot com au 2015 04 struts2
  • 哪个 Swing 布局管理器可以获得我想要的布局?

    我正在尝试按照这个模型制作一个基本的登录菜单 我决定将整个菜单放入 JPanel 中 以便在连接成功后我可以切换到另一个面板 所以我决定使用 Borderlayout 将标题放在北区 将连接按钮放在南区 我将边框布局的中心本身设置为面板 我
  • RMI 中的引用传递问题? [复制]

    这个问题在这里已经有答案了 有人可以告诉我我错在哪里 为什么这个 RMI 聊天应用程序不起作用 目标是通过远程对象或序列化对象实现客户端 服务器和逻辑之间的解耦 import javax swing import java awt even
  • 是否有任何API可以将Microsoft Exchange服务器与Java应用程序集成以进行任务同步?

    我正在尝试将 Java Web 应用程序与 Microsoft Exchange 服务器集成以实现双向日历 即任务 同步 是否有用于此集成的 Java 开源 商业 API 谢谢 文卡特 看一眼j 交易所 http sourceforge n
  • 有多少种方法可以将位图转换为字符串,反之亦然?

    在我的应用程序中 我想以字符串的形式将位图图像发送到服务器 我想知道有多少种方法可以将位图转换为字符串 现在我使用 Base64 格式进行编码和解码 它需要更多的内存 是否有其他可能性以不同的方式做同样的事情 从而消耗更少的内存 现在我正在
  • 如何导入 org.apache.commons.lang3.ArrayUtils;进入 Eclipse [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我如何导入 org apache commons lang3 ArrayUtils 将库添加到 Ecl
  • 容器中的 JVM 计算处理器错误?

    最近我又做了一些研究 偶然发现了这一点 在向 OpenJDK 团队抱怨之前 我想看看是否有其他人观察到这一点 或者不同意我的结论 因此 众所周知 JVM 长期以来忽略了应用于 cgroup 的内存限制 众所周知 现在从 Java 8 更新某
  • 从 @JsonProperty 值获取枚举常量

    我有一个标有 JsonProperty 的枚举 用于使用 Jackson 进行 JSON 序列化 反序列化 并且希望获取给定字符串 JsonProperty 的枚举值 public enum TimeBucket JsonProperty
  • 发生错误。请参阅日志文件 - eclipse juno

    每当我启动 Eclipse Juno 时 都会出现错误 发生错误 请查看日志文件 C Program Files eclipse configuration 1362989254411 log 有的网站说卸载jdk重新安装 我这样做了 但没
  • 当您在数组列表上调用remove(object o)时,它如何比较对象?

    当您在 java 中的数组列表上调用remove object o 时 它如何比较对象以找到要删除的正确对象 它使用指针吗 或者它使用 Comparable 接口来比较对象吗 ArrayList remove 依赖于对象的实现Equal方法
  • 带有 OpenId 提供程序的 Java Spring 安全性

    我有一个 spring MVC 应用程序 另一个客户端应用程序想要使用 open id connect 访问我的 spring 应用程序 如何在服务器端实现开放ID提供商 请帮忙 MITREid 连接 OpenID Connect Java
  • 创建正则表达式匹配数组

    在Java中 我试图将所有正则表达式匹配返回到一个数组 但似乎您只能检查模式是否匹配某些内容 布尔值 如何使用正则表达式匹配来形成与给定字符串中的正则表达式匹配的所有字符串的数组 4城堡的回答 https stackoverflow com
  • 为什么我的代码会产生错误:该语句没有返回结果集[重复]

    这个问题在这里已经有答案了 我正在从 Microsoft SQL Server Studio 执行以下查询 该查询工作正常并显示结果 SELECT INTO temp table FROM md criteria join WHERE us
  • 公共方法与公共 API

    在干净的代码书中 有一个观点是 公共 API 中的 Javadocs 同样 Effective java 一书也有这样的内容 项目 56 为所有公开的 API 元素编写文档注释 所以这就是我的问题 所有公共方法都被视为公共 API 吗 它们
  • 摩尔斯电码 至 英语

    我现在的问题是让 摩尔斯电码转英语 正常工作 将英语转换为莫尔斯电码的第一部分工作正常 我知道以前已经有人问过这个问题 但我不知道我做错了什么 我知道我需要在某个地方进行拆分 但我只是不确定将其放在代码中的何处 现在 莫尔斯电码到英语的部分
  • 防止Java实例化的正确方法[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi

随机推荐

  • 在 SQL 中合并具有重叠日期范围的记录

    编辑 我们当前的服务器是 SQL 2008 R2 因此 LAG LEAD 功能将不起作用 我正在尝试获取表中的多个数据流并将它们组合成 1 个数据流 鉴于下面的 3 个数据流 我希望最终结果是 1 个优先考虑状态 on 的流 递归似乎是最好
  • 如何使用 YouTube javascript API 获取特定“秒”的 YouTube 视频的缩略图或快照?

    我想拍摄 YouTube 视频的缩略图http www youtube com watch v ffaTjpA1scI http www youtube com watch v ffaTjpA1scI30秒或120秒 我如何使用 youtu
  • SHA 足以检查文件重复吗? (PHP 中的 sha1_file)

    假设您想创建一个文件托管站点 供人们上传文件并向他们的朋友发送链接以供稍后检索 并且您想确保文件在我们存储文件的位置重复 那么 PHP 的 sha1 file 是否足以完成该任务 有什么理由不使用 md5 file 来代替吗 对于前端 它将
  • 即席查询/更新是否开始影响您使用 MongoDB 的工作效率?

    我开发一个 ASP MVC 网站已经快一年了 现在完全在 mongodb 上 我大部分时间都喜欢它 使用 C mongodb 驱动程序和 mongovue 等工具 开发效率非常高 然而 我已经开始达到这样一个地步 有些事情我真的希望我有一个
  • 在 SecureField 的 SwiftUI 中切换 isSecureTextEntry

    我想实现在 SecureField 中显示和隐藏密码的功能 以下是 SecureField 的代码 我添加了按钮 该按钮将被检测到显示和隐藏 SecureField 中的文本 但 swiftUI 没有类似的功能是安全文本条目除了切换之外还有
  • 无法找到模块提供者

    我在使用 PowerShell 时遇到问题 几乎就像没有完全安装一样 这很奇怪 因为它是 Windows 10 并且是附带的 在没有锁定的情况下 我尝试使用另一台正在运行的 Windows 10 计算机上的全新副本替换以下目录 C User
  • 如何使用调查包的 svyby 函数对多个列进行循环?

    我已经尝试了很多方法 但我无法解决问题 我发现here https stackoverflow com questions 13402829 r looping through in survey package here https st
  • 每个命令重置外部差异工具

    我最近安装了一个新的差异工具 差异性的 https github com Wilfred difftastic 这扰乱了我将差异复制到剪贴板 或文件 以发送这些内容的习惯 diff external difft As per https d
  • 无法使用 git 克隆任何存储库

    我尝试克隆一些存储库 但总是遇到相同的错误 我在哪里可以找到有关此错误的更多信息 错误日志文件或类似的文件 或者也许有人知道可能出了什么问题 git clone http github com creationix nvm git nvm
  • Visual Studio 2012 生成后事件 - 错误代码 255

    这是我尝试将应用程序可执行文件复制到另一个文件夹并更改其名称 IF ConfigurationName Release SET DESTINATION ProjectDir Output Distribution IF NOT EXIST
  • 多重绑定多重选择ListView

    好吧 我这里有一个奇怪的 我想要弄清楚的是如何拥有一个由 ObservableCollection 填充的列表视图 根据第一个列表视图的选择更新另一个由另一个 ObservableCollection 填充的 ListView 然后使用 v
  • URLConnection 和 setUseCaches(true)

    我正在使用当前代码在线程中下载图像 Log d TAG Fetching image BASE URL mURL URLConnection connection InputStream input connection new URL B
  • Hstore 和 Rails

    我正在尝试使用最新版本的 activerecord postgres hstore gem 在 Rails 3 2 9 项目中使用 Hstore 但在使用 ActiveRecord 提供的 store accessor 来获取 Hstore
  • 获取浏览器中正在查看的当前页面(可能吗?)

    我想知道 作为一名 Android 开发人员 我是否可以知道浏览器应用程序当前是否打开 如果是 正在查看哪个页面 网址 如果是这样 我将如何去做这件事 如果没有 我也很想知道 所以我不会再搜索了 谢谢 奥姆里 我不知道是否有可能知道浏览器应
  • solr索引嵌套文档

    solr支持嵌套文档吗 有没有更好的方法来实现这种文档
  • Identity Server:在 MVC 客户端的混合流中添加访问令牌的声明

    我已阅读文档并遵循示例 但无法将用户声明放入访问令牌中 我的客户端不是 ASP NET core 因此 MVC 客户端的配置与 v4 示例不同 除非我误解了文档 否则在创建访问令牌时 ApiResources 用于填充配置文件服务中的 Re
  • findbugs-maven-plugin 不执行任何操作

    我不明白 我想在 Maven 3 项目站点中启用 findbugs 报告 并通过将其添加到我的 pom xml 中来实现 如所述here http mojo codehaus org findbugs maven plugin usage
  • 使用反射从泛型结构获取类型参数

    想象一下我有以下结构 type MyGeneric T string int struct 我想在创建新的 MyGeneric 时检查用于实例化该结构的泛型是字符串还是 int myGenericString MyGeneric strin
  • 使用 r 写入和更新 DB2 表

    我不知道如何更新 R 中现有的 DB2 数据库或更新其中的单个值 除了非常一般的信息之外 我在网上找不到关于这个主题的太多信息 但没有具体的例子 library RJDBC teachersalaries data frame name c
  • Java OutputStream 读取字符串行

    我使用一个 API 更多信息 见下文 它接受输出流捕获数据 相反 我想提供一个Consumer of Strings它消耗了一行又一行的数据 因此我必须编写一个 OutputStream 实现来包装这样的 Consumer 这是我能想到的最