Java:作为InputStream访问字符串列表

时间:2022-05-09 20:44:22

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

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

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。