有InputStream
包装UTF-8 String
列表的方式吗?我想做点什么:
InputStream in = new XyzInputStream( List<String> lines )
答案 0 :(得分:8)
您可以阅读ByteArrayOutputStream
,然后使用byte[]
创建源ByteArrayInputStream
数组。
所以按如下方式创建数组:
List<String> source = new ArrayList<String>();
source.add("one");
source.add("two");
source.add("three");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for (String line : source) {
baos.write(line.getBytes());
}
byte[] bytes = baos.toByteArray();
从中读取就像:
InputStream in = new ByteArrayInputStream(bytes);
或者,根据您的目标,StringReader
可能会更好。
答案 1 :(得分:4)
简而言之,不,没有办法使用现有的JDK类来实现这一点。但是,您可以实现从字符串列表中读取的自己的InputStream。
编辑:Dave Web上面有一个答案,我认为这是要走的路。如果你需要一个可重用的类,那么这样的事情可能会:
public class StringsInputStream<T extends Iterable<String>> extends InputStream {
private ByteArrayInputStream bais = null;
public StringsInputStream(final T strings) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
for (String line : strings) {
outputStream.write(line.getBytes());
}
bais = new ByteArrayInputStream(outputStream.toByteArray());
}
@Override
public int read() throws IOException {
return bais.read();
}
@Override
public int read(byte[] b) throws IOException {
return bais.read(b);
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
return bais.read(b, off, len);
}
@Override
public long skip(long n) throws IOException {
return bais.skip(n);
}
@Override
public int available() throws IOException {
return bais.available();
}
@Override
public void close() throws IOException {
bais.close();
}
@Override
public synchronized void mark(int readlimit) {
bais.mark(readlimit);
}
@Override
public synchronized void reset() throws IOException {
bais.reset();
}
@Override
public boolean markSupported() {
return bais.markSupported();
}
public static void main(String[] args) throws Exception {
List source = new ArrayList();
source.add("foo ");
source.add("bar ");
source.add("baz");
StringsInputStream<List<String>> in = new StringsInputStream<List<String>>(source);
int read = in.read();
while (read != -1) {
System.out.print((char) read);
read = in.read();
}
}
}
这基本上是ByteArrayInputStream
的适配器。
答案 2 :(得分:3)
您可以将所有行连接在一起以创建String,然后使用String#getBytes
将其转换为字节数组,并将其传递给ByteArrayInputStream。然而,这不是最有效的方法。
答案 3 :(得分:0)
您也可以这样创建可序列化列表
List<String> quarks = Arrays.asList(
"up", "down", "strange", "charm", "top", "bottom"
);
//serialize the List
//note the use of abstract base class references
try{
//use buffering
OutputStream file = new FileOutputStream( "quarks.ser" );
OutputStream buffer = new BufferedOutputStream( file );
ObjectOutput output = new ObjectOutputStream( buffer );
try{
output.writeObject(quarks);
}
finally{
output.close();
}
}
catch(IOException ex){
fLogger.log(Level.SEVERE, "Cannot perform output.", ex);
}
//deserialize the quarks.ser file
//note the use of abstract base class references
try{
//use buffering
InputStream file = new FileInputStream( "quarks.ser" );
InputStream buffer = new BufferedInputStream( file );
ObjectInput input = new ObjectInputStream ( buffer );
try{
//deserialize the List
List<String> recoveredQuarks = (List<String>)input.readObject();
//display its data
for(String quark: recoveredQuarks){
System.out.println("Recovered Quark: " + quark);
}
}
finally{
input.close();
}
}
catch(ClassNotFoundException ex){
fLogger.log(Level.SEVERE, "Cannot perform input. Class not found.", ex);
}
catch(IOException ex){
fLogger.log(Level.SEVERE, "Cannot perform input.", ex);
}
答案 4 :(得分:0)
你可以做类似的事情:
它只实现了InputStream的read()方法,并且有一个连接的InputStream列表。一旦读取EOF,它就会从下一个InputStream开始读取。只需将字符串转换为ByteArrayInputStreams。
答案 5 :(得分:0)
您可以创建某种IterableInputStream
public class IterableInputStream<T> extends InputStream {
public static final int EOF = -1;
private static final InputStream EOF_IS = new InputStream() {
@Override public int read() throws IOException {
return EOF;
}
};
private final Iterator<T> iterator;
private final Function<T, byte[]> mapper;
private InputStream current;
public IterableInputStream(Iterable<T> iterable, Function<T, byte[]> mapper) {
this.iterator = iterable.iterator();
this.mapper = mapper;
next();
}
@Override
public int read() throws IOException {
int n = current.read();
while (n == EOF && current != EOF_IS) {
next();
n = current.read();
}
return n;
}
private void next() {
current = iterator.hasNext()
? new ByteArrayInputStream(mapper.apply(iterator.next()))
: EOF_IS;
}
}
要使用它
public static void main(String[] args) throws IOException {
Iterable<String> strings = Arrays.asList("1", "22", "333", "4444");
try (InputStream is = new IterableInputStream<String>(strings, String::getBytes)) {
for (int b = is.read(); b != -1; b = is.read()) {
System.out.print((char) b);
}
}
}
答案 6 :(得分:0)
就我而言,我必须转换等效文件中的字符串列表(每行换行)。
这是我的解决方案:
List<String> inputList = Arrays.asList("line1", "line2", "line3");
byte[] bytes = inputList.stream().collect(Collectors.joining("\n")).getBytes();
InputStream inputStream = new ByteArrayInputStream(bytes);