【问题标题】:java - modify and return a buffredInputStreamjava - 修改并返回一个buffredInputStream
【发布时间】:2020-09-05 12:31:29
【问题描述】:

我有一个从 FileInputStream 对象获得的 BufferedInputStream,例如:

BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream)

现在,我想从 buffredInputStream 中删除字符 {}(我知道文件中有这些字符)。 我认为我可以像string replace 那样轻松地做到这一点,但我发现使用 BufferedInputStream 没有简单的方法。

任何想法如何替换 BufferedInputStream 中的那些特定字符并返回新修改的 BufferedInputStream?

编辑: 最后我想决定一个文件的字符集。虽然字符 {} 给我带来了一些问题,所以我想在决定文件的字符集之前删除它们。这表明我正在尝试确定字符集:

static String detectCharset(File file) {
    try (FileInputStream fileInputStream = new FileInputStream(file);
             BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream)) {
        CharsetDetector charsetDetector=new CharsetDetector();
        charsetDetector.setText(bufferedInputStream);
        charsetDetector.enableInputFilter(true);
        CharsetMatch cm=charsetDetector.detect();
        return cm.getName();
    } catch (Exception e) {
        return null;
    }
}

【问题讨论】:

  • BufferedInputStream 不知道字符。考虑改用BufferedReader。你能用BufferedReader吗?
  • 我敢打赌,在你的实际任务描述中没有BufferedInputStream的要求。显然,您的出发点是一个文件。然后,说出你真正想要做什么以及实际结果应该是什么。肯定不是以BufferedInputStream 本身为目的。
  • @Holger 请看我的编辑
  • {} 的字符给我带来了一些问题”是什么意思?一个应该检测字节序列字符集的软件会被{} 字符这样的小东西所迷惑?听起来你应该放弃那个坏掉的工具而不是添加一个杂物。如果您知道文件包含{} 字符,甚至在字节被解码之前,这意味着您比CharsetDetector 更了解文件具有哪个实际字符集。然后,只需使用已知的字符集。

标签: java file-io stream buffer


【解决方案1】:

注意:添加注释以响应您对问题所做的编辑:除非您知道编码,否则您无法真正从字节袋中过滤 },所以如果您想过滤 } 以猜测编码您处于先有鸡还是先有蛋的情况。不过,我不明白删除 { 和 } 如何以某种方式帮助字符集编码检测器。这听起来像是探测器有问题,或者你误解了它在做什么。如果必须,请重写您的大脑,将其视为“从输入流中删除字节 123 和 125”而不是“从输入流中删除字符 { 和 }”,这样您就更接近于可行的工作定义。同样的原则也适用,除了你用几乎相同的方法写一个FilterInputStream而不是FilterReader,除了123125而不是'{''}'

-- 原始答案--

[1] InputStream 指的是字节,Reader 是相同的概念,除了字符。说:“从输入流中过滤所有{”是没有意义的。说“从输入流中过滤所有出现的字节'123'”是有道理的。如果是 UTF-8 或 ASCII,这两者是等价的,但不能保证,它在任何方面都不是“好”的代码。要将文件作为文本读取,方法如下:

import java.nio.file.*;

Path p = Paths.get("/path/to/file");
try (BufferedReader br = Files.newBufferedReader(p)) {
    // operate on the reader here
}

请注意,与大多数 java 方法不同,Files 中的方法假定为 UTF_8。您可以改为显式指定编码 (Files.newBufferedReader(p, [ENCODING HERE]))。您永远不应该依赖系统默认编码是正确的;除非您知道文件是以何种文本编码编写的,否则您无法将文件作为文本读取!

如果您必须使用旧 API:

try (FileInputStream fis = new FileInputStream("/path/to/file");
     InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);
     BufferedReader br = new BufferedReader(isr)) {
}

请注意,您必须在此处指定字符集,否则会以微妙的方式破坏。

[2] 要过滤掉某些字符,您可以“内联”(在从阅读器读取字符的代码中)执行此操作,这很简单,或者您可以创建一个可以执行此操作的包装流。比如:

class RemoveBracesReader extends java.io.FilterReader {
    public RemoveBracesReader(Reader in) {
        super(in);
    }

    public int read() throws java.io.IOException {
        while (true) {
            int c = in.read();
            if (c != '{' && c != '}') return c;
        }
    }
}

【讨论】:

  • 感谢您的详细回复。请看我的编辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-03
  • 2018-03-09
  • 2021-11-17
  • 1970-01-01
  • 2013-10-28
相关资源
最近更新 更多