Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: accessing a List of Strings as an InputStream

Tags:

java

java-io

Is there any way InputStream wrapping a list of UTF-8 String? I'd like to do something like:

InputStream in = new XyzInputStream( List<String> lines )
like image 626
Marc Polizzi Avatar asked Mar 23 '12 10:03

Marc Polizzi


People also ask

Which method is used to read a String from InputStream?

read() method reads the next byte of the data from the the input stream and returns int in the range of 0 to 255.

How do you read all bytes from InputStream?

Since Java 9, we can use the readAllBytes() method from InputStream class to read all bytes into a byte array. This method reads all bytes from an InputStream object at once and blocks until all remaining bytes have read and end of a stream is detected, or an exception is thrown.

How do I convert Inputstreamreader to InputStream?

2. Reader to InputStream in plain Java. In this example, first, we need to read all characters from given StringReader and aggregate them in StringBuilder . Then, using ByteArrayInputStream we create an instance of InputStream that wraps bytes array taken from String .


3 Answers

You can read from a ByteArrayOutputStream and you can create your source byte[] array using 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.

like image 145
Dave Webb Avatar answered Oct 11 '22 08:10

Dave Webb


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.

like image 5
benmmurphy Avatar answered Oct 11 '22 06:10

benmmurphy


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.

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:


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.

like image 4
Jon Avatar answered Oct 11 '22 07:10

Jon