Is there any way InputStream
wrapping a list of UTF-8 String
? I'd like to do something like:
InputStream是否可以包装UTF-8字符串列表?我想做的是:
InputStream in = new XyzInputStream( List<String> lines )
5 个解决方案
#1
3
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。然而,这并不是最有效的方法。
#2
6
You can read from a ByteArrayOutputStream
and you can create your source byte[]
array using a ByteArrayInputStream
.
您可以从ByteArrayOutputStream读取数据,并可以使用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.
或者,根据您的尝试,StringReader可能更好。
#3
4
In short, no, there is no way of doing this using existing JDK classes. You could, however, implement your own InputStream that 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的适配器。
#4
0
you can also do this way create a Serializable List
您还可以通过这种方式创建一个Serializable列表
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);
}
#5
0
You can do something similar to this:
你可以做类似的事情:
https://commons.apache.org/sandbox/flatfile/xref/org/apache/commons/flatfile/util/ConcatenatedInputStream.html
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。
#1
3
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。然而,这并不是最有效的方法。
#2
6
You can read from a ByteArrayOutputStream
and you can create your source byte[]
array using a ByteArrayInputStream
.
您可以从ByteArrayOutputStream读取数据,并可以使用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.
或者,根据您的尝试,StringReader可能更好。
#3
4
In short, no, there is no way of doing this using existing JDK classes. You could, however, implement your own InputStream that 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的适配器。
#4
0
you can also do this way create a Serializable List
您还可以通过这种方式创建一个Serializable列表
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);
}
#5
0
You can do something similar to this:
你可以做类似的事情:
https://commons.apache.org/sandbox/flatfile/xref/org/apache/commons/flatfile/util/ConcatenatedInputStream.html
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。