Java: accessing a List of Strings as an InputStream
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 )
java java-io
add a comment |
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 )
java java-io
Can you share the situation, why you want this?
– Chandra Sekhar
Mar 23 '12 at 10:41
2
Note thatInputStreamdeals with binary data. Strings are text data. Which encoding are you interested in?
– Jon Skeet
Mar 23 '12 at 10:43
You're right I forgot to precise : UTF-8 only.
– Marc Polizzi
Mar 23 '12 at 10:47
How did you finally accomplish creating an InputStream from List<String> Marc? I have to do the same thing. Any Input will help.
– Rahul Dabas
Sep 25 '14 at 19:05
add a comment |
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 )
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 )
java java-io
java java-io
edited Mar 23 '12 at 10:56
Andrew Thompson
154k28164347
154k28164347
asked Mar 23 '12 at 10:38
Marc PolizziMarc Polizzi
7,11232649
7,11232649
Can you share the situation, why you want this?
– Chandra Sekhar
Mar 23 '12 at 10:41
2
Note thatInputStreamdeals with binary data. Strings are text data. Which encoding are you interested in?
– Jon Skeet
Mar 23 '12 at 10:43
You're right I forgot to precise : UTF-8 only.
– Marc Polizzi
Mar 23 '12 at 10:47
How did you finally accomplish creating an InputStream from List<String> Marc? I have to do the same thing. Any Input will help.
– Rahul Dabas
Sep 25 '14 at 19:05
add a comment |
Can you share the situation, why you want this?
– Chandra Sekhar
Mar 23 '12 at 10:41
2
Note thatInputStreamdeals with binary data. Strings are text data. Which encoding are you interested in?
– Jon Skeet
Mar 23 '12 at 10:43
You're right I forgot to precise : UTF-8 only.
– Marc Polizzi
Mar 23 '12 at 10:47
How did you finally accomplish creating an InputStream from List<String> Marc? I have to do the same thing. Any Input will help.
– Rahul Dabas
Sep 25 '14 at 19:05
Can you share the situation, why you want this?
– Chandra Sekhar
Mar 23 '12 at 10:41
Can you share the situation, why you want this?
– Chandra Sekhar
Mar 23 '12 at 10:41
2
2
Note that
InputStream deals with binary data. Strings are text data. Which encoding are you interested in?– Jon Skeet
Mar 23 '12 at 10:43
Note that
InputStream deals with binary data. Strings are text data. Which encoding are you interested in?– Jon Skeet
Mar 23 '12 at 10:43
You're right I forgot to precise : UTF-8 only.
– Marc Polizzi
Mar 23 '12 at 10:47
You're right I forgot to precise : UTF-8 only.
– Marc Polizzi
Mar 23 '12 at 10:47
How did you finally accomplish creating an InputStream from List<String> Marc? I have to do the same thing. Any Input will help.
– Rahul Dabas
Sep 25 '14 at 19:05
How did you finally accomplish creating an InputStream from List<String> Marc? I have to do the same thing. Any Input will help.
– Rahul Dabas
Sep 25 '14 at 19:05
add a comment |
6 Answers
6
active
oldest
votes
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.
Done this way already; I'd like to avoid this copy.
– Marc Polizzi
Mar 23 '12 at 10:48
You can implement a InputStream yourself and convert each String to a byte array as you go along and wrap it in a ByteArrayInputStream and forward the calls to the ByteArrayInputStream. Though, seeing as you will have to have logic dealing with splitting reads across Strings it's probably just as easy to do all the logic yourself and not use ByteArrayInputStream at all.
– benmmurphy
Mar 23 '12 at 10:53
@Marc avoiding this copy is not necessary a good idea. It allows you to process all the data at once. If the strings are small this can save you a lot of object allocations. It can be faster and in some cases even consume less memory. Whatever you do, benchmark it on sample data and make sure it really is more efficient.
– Piotr Praszmo
Mar 23 '12 at 11:26
@Marc You can avoid the copy, but not without writing a significant amount of code. You would have to implement InputStream yourself, and somehow adapt all of its methods to working over a List of Strings, which will be an enormous pain to do, and won't buy you that much in terms of performance or reduced memory footprint.
– Jon
Mar 23 '12 at 11:41
add a comment |
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.
This is the best way of doing it if it's a one-off. If you have to reuse instances of the InputStream all over the place though, you could always implement the InputStream interface, and do all of the above under the hood.
– Jon
Mar 23 '12 at 11:10
Good example, but it would be nice to encourage best practice by specifying a charset duringgetBytes().
– Duncan Jones
Mar 11 '15 at 9:37
add a comment |
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.
add a comment |
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);
}
add a comment |
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.
add a comment |
You can create some kind of 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);
}
}
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f9837754%2fjava-accessing-a-list-of-strings-as-an-inputstream%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
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.
Done this way already; I'd like to avoid this copy.
– Marc Polizzi
Mar 23 '12 at 10:48
You can implement a InputStream yourself and convert each String to a byte array as you go along and wrap it in a ByteArrayInputStream and forward the calls to the ByteArrayInputStream. Though, seeing as you will have to have logic dealing with splitting reads across Strings it's probably just as easy to do all the logic yourself and not use ByteArrayInputStream at all.
– benmmurphy
Mar 23 '12 at 10:53
@Marc avoiding this copy is not necessary a good idea. It allows you to process all the data at once. If the strings are small this can save you a lot of object allocations. It can be faster and in some cases even consume less memory. Whatever you do, benchmark it on sample data and make sure it really is more efficient.
– Piotr Praszmo
Mar 23 '12 at 11:26
@Marc You can avoid the copy, but not without writing a significant amount of code. You would have to implement InputStream yourself, and somehow adapt all of its methods to working over a List of Strings, which will be an enormous pain to do, and won't buy you that much in terms of performance or reduced memory footprint.
– Jon
Mar 23 '12 at 11:41
add a comment |
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.
Done this way already; I'd like to avoid this copy.
– Marc Polizzi
Mar 23 '12 at 10:48
You can implement a InputStream yourself and convert each String to a byte array as you go along and wrap it in a ByteArrayInputStream and forward the calls to the ByteArrayInputStream. Though, seeing as you will have to have logic dealing with splitting reads across Strings it's probably just as easy to do all the logic yourself and not use ByteArrayInputStream at all.
– benmmurphy
Mar 23 '12 at 10:53
@Marc avoiding this copy is not necessary a good idea. It allows you to process all the data at once. If the strings are small this can save you a lot of object allocations. It can be faster and in some cases even consume less memory. Whatever you do, benchmark it on sample data and make sure it really is more efficient.
– Piotr Praszmo
Mar 23 '12 at 11:26
@Marc You can avoid the copy, but not without writing a significant amount of code. You would have to implement InputStream yourself, and somehow adapt all of its methods to working over a List of Strings, which will be an enormous pain to do, and won't buy you that much in terms of performance or reduced memory footprint.
– Jon
Mar 23 '12 at 11:41
add a comment |
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.
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.
edited Mar 23 '12 at 10:47
Riduidel
18k1160134
18k1160134
answered Mar 23 '12 at 10:46
benmmurphybenmmurphy
1,93811626
1,93811626
Done this way already; I'd like to avoid this copy.
– Marc Polizzi
Mar 23 '12 at 10:48
You can implement a InputStream yourself and convert each String to a byte array as you go along and wrap it in a ByteArrayInputStream and forward the calls to the ByteArrayInputStream. Though, seeing as you will have to have logic dealing with splitting reads across Strings it's probably just as easy to do all the logic yourself and not use ByteArrayInputStream at all.
– benmmurphy
Mar 23 '12 at 10:53
@Marc avoiding this copy is not necessary a good idea. It allows you to process all the data at once. If the strings are small this can save you a lot of object allocations. It can be faster and in some cases even consume less memory. Whatever you do, benchmark it on sample data and make sure it really is more efficient.
– Piotr Praszmo
Mar 23 '12 at 11:26
@Marc You can avoid the copy, but not without writing a significant amount of code. You would have to implement InputStream yourself, and somehow adapt all of its methods to working over a List of Strings, which will be an enormous pain to do, and won't buy you that much in terms of performance or reduced memory footprint.
– Jon
Mar 23 '12 at 11:41
add a comment |
Done this way already; I'd like to avoid this copy.
– Marc Polizzi
Mar 23 '12 at 10:48
You can implement a InputStream yourself and convert each String to a byte array as you go along and wrap it in a ByteArrayInputStream and forward the calls to the ByteArrayInputStream. Though, seeing as you will have to have logic dealing with splitting reads across Strings it's probably just as easy to do all the logic yourself and not use ByteArrayInputStream at all.
– benmmurphy
Mar 23 '12 at 10:53
@Marc avoiding this copy is not necessary a good idea. It allows you to process all the data at once. If the strings are small this can save you a lot of object allocations. It can be faster and in some cases even consume less memory. Whatever you do, benchmark it on sample data and make sure it really is more efficient.
– Piotr Praszmo
Mar 23 '12 at 11:26
@Marc You can avoid the copy, but not without writing a significant amount of code. You would have to implement InputStream yourself, and somehow adapt all of its methods to working over a List of Strings, which will be an enormous pain to do, and won't buy you that much in terms of performance or reduced memory footprint.
– Jon
Mar 23 '12 at 11:41
Done this way already; I'd like to avoid this copy.
– Marc Polizzi
Mar 23 '12 at 10:48
Done this way already; I'd like to avoid this copy.
– Marc Polizzi
Mar 23 '12 at 10:48
You can implement a InputStream yourself and convert each String to a byte array as you go along and wrap it in a ByteArrayInputStream and forward the calls to the ByteArrayInputStream. Though, seeing as you will have to have logic dealing with splitting reads across Strings it's probably just as easy to do all the logic yourself and not use ByteArrayInputStream at all.
– benmmurphy
Mar 23 '12 at 10:53
You can implement a InputStream yourself and convert each String to a byte array as you go along and wrap it in a ByteArrayInputStream and forward the calls to the ByteArrayInputStream. Though, seeing as you will have to have logic dealing with splitting reads across Strings it's probably just as easy to do all the logic yourself and not use ByteArrayInputStream at all.
– benmmurphy
Mar 23 '12 at 10:53
@Marc avoiding this copy is not necessary a good idea. It allows you to process all the data at once. If the strings are small this can save you a lot of object allocations. It can be faster and in some cases even consume less memory. Whatever you do, benchmark it on sample data and make sure it really is more efficient.
– Piotr Praszmo
Mar 23 '12 at 11:26
@Marc avoiding this copy is not necessary a good idea. It allows you to process all the data at once. If the strings are small this can save you a lot of object allocations. It can be faster and in some cases even consume less memory. Whatever you do, benchmark it on sample data and make sure it really is more efficient.
– Piotr Praszmo
Mar 23 '12 at 11:26
@Marc You can avoid the copy, but not without writing a significant amount of code. You would have to implement InputStream yourself, and somehow adapt all of its methods to working over a List of Strings, which will be an enormous pain to do, and won't buy you that much in terms of performance or reduced memory footprint.
– Jon
Mar 23 '12 at 11:41
@Marc You can avoid the copy, but not without writing a significant amount of code. You would have to implement InputStream yourself, and somehow adapt all of its methods to working over a List of Strings, which will be an enormous pain to do, and won't buy you that much in terms of performance or reduced memory footprint.
– Jon
Mar 23 '12 at 11:41
add a comment |
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.
This is the best way of doing it if it's a one-off. If you have to reuse instances of the InputStream all over the place though, you could always implement the InputStream interface, and do all of the above under the hood.
– Jon
Mar 23 '12 at 11:10
Good example, but it would be nice to encourage best practice by specifying a charset duringgetBytes().
– Duncan Jones
Mar 11 '15 at 9:37
add a comment |
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.
This is the best way of doing it if it's a one-off. If you have to reuse instances of the InputStream all over the place though, you could always implement the InputStream interface, and do all of the above under the hood.
– Jon
Mar 23 '12 at 11:10
Good example, but it would be nice to encourage best practice by specifying a charset duringgetBytes().
– Duncan Jones
Mar 11 '15 at 9:37
add a comment |
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.
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.
edited Mar 23 '12 at 11:15
answered Mar 23 '12 at 10:48
Dave WebbDave Webb
157k49282291
157k49282291
This is the best way of doing it if it's a one-off. If you have to reuse instances of the InputStream all over the place though, you could always implement the InputStream interface, and do all of the above under the hood.
– Jon
Mar 23 '12 at 11:10
Good example, but it would be nice to encourage best practice by specifying a charset duringgetBytes().
– Duncan Jones
Mar 11 '15 at 9:37
add a comment |
This is the best way of doing it if it's a one-off. If you have to reuse instances of the InputStream all over the place though, you could always implement the InputStream interface, and do all of the above under the hood.
– Jon
Mar 23 '12 at 11:10
Good example, but it would be nice to encourage best practice by specifying a charset duringgetBytes().
– Duncan Jones
Mar 11 '15 at 9:37
This is the best way of doing it if it's a one-off. If you have to reuse instances of the InputStream all over the place though, you could always implement the InputStream interface, and do all of the above under the hood.
– Jon
Mar 23 '12 at 11:10
This is the best way of doing it if it's a one-off. If you have to reuse instances of the InputStream all over the place though, you could always implement the InputStream interface, and do all of the above under the hood.
– Jon
Mar 23 '12 at 11:10
Good example, but it would be nice to encourage best practice by specifying a charset during
getBytes().– Duncan Jones
Mar 11 '15 at 9:37
Good example, but it would be nice to encourage best practice by specifying a charset during
getBytes().– Duncan Jones
Mar 11 '15 at 9:37
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
edited Mar 23 '12 at 13:37
answered Mar 23 '12 at 10:50
JonJon
2,44551932
2,44551932
add a comment |
add a comment |
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);
}
add a comment |
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);
}
add a comment |
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);
}
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);
}
answered Mar 23 '12 at 10:55
Riddhish.ChaudhariRiddhish.Chaudhari
7121522
7121522
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Mar 23 '12 at 10:59
benmmurphybenmmurphy
1,93811626
1,93811626
add a comment |
add a comment |
You can create some kind of 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);
}
}
}
add a comment |
You can create some kind of 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);
}
}
}
add a comment |
You can create some kind of 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);
}
}
}
You can create some kind of 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);
}
}
}
answered Nov 16 '18 at 3:10
Mike ShauneuMike Shauneu
1,743915
1,743915
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f9837754%2fjava-accessing-a-list-of-strings-as-an-inputstream%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Can you share the situation, why you want this?
– Chandra Sekhar
Mar 23 '12 at 10:41
2
Note that
InputStreamdeals with binary data. Strings are text data. Which encoding are you interested in?– Jon Skeet
Mar 23 '12 at 10:43
You're right I forgot to precise : UTF-8 only.
– Marc Polizzi
Mar 23 '12 at 10:47
How did you finally accomplish creating an InputStream from List<String> Marc? I have to do the same thing. Any Input will help.
– Rahul Dabas
Sep 25 '14 at 19:05