Java:将字符串列表作为 InputStream 访问
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9837754/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java: accessing a List of Strings as an InputStream
提问by Marc Polizzi
Is there any way InputStream
wrapping a list of UTF-8 String
? I'd like to do something like:
有没有办法InputStream
包装一个 UTF-8 列表String
?我想做类似的事情:
InputStream in = new XyzInputStream( List<String> lines )
采纳答案by benmmurphy
You can concatenate all the lines together to create a String then convert it to a byte array using String#getBytes
and pass it into ByteArrayInputStream. However this is not the most efficient way of doing it.
您可以将所有行连接在一起以创建一个字符串,然后使用将其转换为字节数组String#getBytes
并将其传递给ByteArrayInputStream。然而,这并不是最有效的方法。
回答by Dave Webb
You can read from a ByteArrayOutputStream
and you can create your source byte[]
array using a ByteArrayInputStream
.
您可以从 a 读取ByteArrayOutputStream
,也可以byte[]
使用 a创建源数组ByteArrayInputStream
。
So create the array as follows:
所以创建数组如下:
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();
And reading from it is as simple as:
从中阅读就像这样简单:
InputStream in = new ByteArrayInputStream(bytes);
Alternatively, depending on what you're trying to do, a StringReader
might be better.
或者,根据您尝试执行的操作,aStringReader
可能更好。
回答by Jon
In short, no, there is no way of doing this using existing JDK classes. You could, however, implement your own InputStreamthat read from a List of Strings.
简而言之,不,使用现有的 JDK 类无法做到这一点。但是,您可以实现自己的从字符串列表中读取的InputStream。
EDIT: Dave Web has an answer above, which I think is the way to go. If you need a reusable class, then something like this might do:
编辑: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();
}
}
}
This basically an adapter for ByteArrayInputStream
.
这基本上是ByteArrayInputStream
.
回答by Riddhish.Chaudhari
you can also do this way create a Serializable List
您也可以通过这种方式创建一个可序列化的列表
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);
}
回答by benmmurphy
You can do something similar to this:
你可以做类似的事情:
It just implements the read() method of InputStream and has a list of InputStreams it is concatenating. Once it reads an EOF it starts reading from the next InputStream. Just convert the Strings to ByteArrayInputStreams.
它只是实现了 InputStream 的 read() 方法,并有一个它正在连接的 InputStreams 列表。一旦它读取一个 EOF,它就会从下一个 InputStream 开始读取。只需将字符串转换为 ByteArrayInputStreams。
回答by Mike Shauneu
You can create some kind of IterableInputStream
您可以创建某种 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;
}
}
To use it
使用它
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);
}
}
}
回答by freedev
In my case I had to convert a list of string in the equivalent file (with a line feed for each line).
在我的情况下,我必须转换等效文件中的字符串列表(每行都有一个换行符)。
This was my solution:
这是我的解决方案:
List<String> inputList = Arrays.asList("line1", "line2", "line3");
byte[] bytes = inputList.stream().collect(Collectors.joining("\n")).getBytes();
InputStream inputStream = new ByteArrayInputStream(bytes);