Java 使用FilterInputStream删除InputStream的其余部分

Java 使用FilterInputStream删除InputStream的其余部分,java,yaml,java-io,Java,Yaml,Java Io,我计划使用Java处理标记文本文件,这些文件以YAML格式在文档开头指定附加的元信息,如标题、作者、创建日期等。下面是一个例子: --- title: An example document author: Paul created: 2013-05-19 --- The _body_ of this document is written in **Markdown**. 对于解析YAML数据,我可以使用。据我所知,您可以通过方法YAML.load()和YAML.loadAll()从jav

我计划使用Java处理标记文本文件,这些文件以YAML格式在文档开头指定附加的元信息,如标题、作者、创建日期等。下面是一个例子:

---
title: An example document
author: Paul
created: 2013-05-19
---

The _body_ of this document is
written in **Markdown**.
对于解析YAML数据,我可以使用。据我所知,您可以通过方法
YAML.load()
YAML.loadAll()
java.io.InputStream
java.io.Reader
String
加载YAML文档

我不想使用从
字符串读取的版本,因为这将导致大文件的性能问题。但是将文件作为
InputStream
处理失败,因为该流不代表有效的YAML文档。只有流的第一部分表示有效文档

因此,我的问题是:如何使用
java.io.FilterInputStream
/
java.io.FilterReader
或其他方法生成流,在第二次
--
之后停止,以使整个流是有效的YAML?

以下是我的解决方案(Scala代码):

import java.io.InputStreamReader
导入java.io.InputStream
导入java.nio.charset.charset
导入scala.collection.mutable.Queue
/**
*给定“InputStream”中包含的元数据的读取器。
*
*@constructor使用给定的“字符集”创建新的元数据读取器。
*底层输入流中的@param
*@param流的字符集编码
*/
类MetadataReader(in:InputStream,charset:charset)
扩展InputStreamReader(in,字符集){
private val lookahead=Queue.empty[Int]//用于前瞻的缓冲区
private var afterNewline=true//表示最后一个字符是换行符
私有变量分隔符=0//行中分隔符字符的数目('-')
/**
*使用系统默认的“字符集”创建新的MetadataReader。
*
*底层输入流中的@param
*/
def this(in:InputStream)=this(in,Charset.defaultCharset())
/**
*读下一个字符。
*
*@返回下一个字符
*/
覆盖def读取:Int=
如果(除法器==2){
-1
}否则,如果(!lookahead.isEmpty){
向前看。退出队列
}否则{
//读下一个字符
def readNext:Int=
if(lookahead.length==3){
除法器+=1
阅读
}否则{
val c=超级读取
如果(c=='-'){
向前看。排队(c)
readNext
}否则{
向前看。排队(c)
向前看。退出队列
}
}
readNext
}
/**
*将字符读入缓冲区字符数组。
*
*@param buf缓冲区数组
*@param off要在数组中开始的偏移量
*@param len要读取的字符数
*@return实际读取的字符数
*/
覆盖def读取(buf:Array[Char],off:Int,len:Int):Int={
var j=0
用于(i=关闭){
buf(i)=c.toChar
j+=1
}
}
J
}
}
您可以这样使用它:

val yaml=新的yaml
val mr=新MetadataReader(新文件输入流(
新文件(“src/test/resources/yaml test.txt”)、Charset.forName(“UTF-8”))
println(yaml.load(mr))
mis.close()

感谢您的反馈。

在希望YAML解析器停止的位置添加“…”(三点)。

这是一个简洁的解决方案,但我必须在
--
之后停止以兼容。