equivalent to Files.readAllLines() for InputStream or Reader? - java

I have a file that I've been reading into a List via the following method:
List<String> doc = java.nio.file.Files.readAllLines(new File("/path/to/src/resources/citylist.csv").toPath(), StandardCharsets.UTF_8);
Is there any nice (single-line) Java 7/8/nio2 way to pull off the same feat with a file that's inside an executable Jar (and presumably, has to be read with an InputStream)? Perhaps a way to open an InputStream via the classloader, then somehow coerce/transform/wrap it into a Path object? Or some new subclass of InputStream or Reader that contains an equivalent to File.readAllLines(...)?
I know I could do it the traditional way in a half page of code, or via some external library... but before I do, I want to make sure that recent releases of Java can't already do it "out of the box".

An InputStream represents a stream of bytes. Those bytes don't necessarily form (text) content that can be read line by line.
If you know that the InputStream can be interpreted as text, you can wrap it in a InputStreamReader and use BufferedReader#lines() to consume it line by line.
try (InputStream resource = Example.class.getResourceAsStream("resource")) {
List<String> doc =
new BufferedReader(new InputStreamReader(resource,
StandardCharsets.UTF_8)).lines().collect(Collectors.toList());
}

You can use Apache Commons IOUtils#readLines:
List<String> doc = IOUtils.readLines(inputStream, StandardCharsets.UTF_8);

Related

Read a text file in JAVA

Text file can be directly read using FileReader & BufferedReader classes.
In several technote, it is mentioned to get the text file as a input stream, then convert to Inputstreamreader and then BufferedReader.
Any reasons why we need to use InputStream approach
FileReader is convenience class for reading character files. The constructors of this class assume that the default character encoding and the default byte-buffer size are appropriate. To specify these values yourself, construct an InputStreamReader on a FileInputStream.
Complement to this answer...
There really isn't a need to use a BufferedReader if you don't need to, except that it has the very convenient .readLine() method. That's the first point.
Second, and more importantly:
Use JSR 203. Don't use File anymore.
Use try-with-resources.
Both of them appeared in Java 7. So, the new way to read a text file is as such:
final Path path = Paths.get("path/to/the/file");
try (
final BufferedReader reader = Files.newBufferedReader(path,
StandardCharsets.UTF_8);
) {
// use reader here
}
In Java 8, you also have a version of Files.newBufferedReader() which does not take a charset as an argument; this will read in UTF-8 by default. Also in Java 8, you have Files.lines():
try (
final Stream<String> stream = Files.lines(thePath);
) {
// use the stream here
}
And yes, use try-with-resources for such a stream!

Using OpenCSV to convert CSV file to XML using byte array in input

I have a question:
I'm trying to convert my CSV file to XML file and I'm seeing the response of this post: Java lib or app to convert CSV to XML file?
I see that I need use this OpenCSV library and in particular, I must use this code:
CSVReader reader = new CSVReader(new FileReader(startFile));
where String startFile = "./startData.csv";
Now, I don't get a String as startFile, but I have a byte[] because, for other question, I have convert my file in byte[]. How can I use this code with byte[]?
Are there alternatives?
Thanks
Since CSVReader's constructor takes a Reader as parameter, you can pretty much pass anything that's readable to it.
So in your case, you may try using a bytes stream reader, as in:
CSVReader reader = new CSVReader(
new InputStreamReader(
new ByteArrayInputStream(yourByteArray)));

Java - directly reading a file without downloading and storing locally [duplicate]

This question already has answers here:
How do I read / convert an InputStream into a String in Java?
(62 answers)
Closed 8 years ago.
I want to directly read a file, put it into a string without storing the file locally. I used to do this with an old project, but I don't have the source code anymore. I used to be able to get the source of my website this way.
However, I don't remember if I did it by "InputStream to String array of lines to String", or if I directly read it into a String.
Was there a function for this, or am I remembering wrong?
(Note: this function would be the PHP equivalent of file_get_contents($path))
You need to use InputStreamReader to convert from a binary input stream to a Reader which is appropriate for reading text.
After that, you need to read to the end of the reader.
Personally I'd do all this with Guava, which has convenience methods for this sort of thing, e.g. CharStreams.toString(Readable).
When you create the InputStreamReader, make sure you supply the appropriate character encoding - if you don't, you'll get junk text out (just like trying to play an MP3 file as if it were a WAV, for example).
Check out apache-commons-io and for your use case FileUtils.readFileToString(File file)
(should not be to hard to get a File form the path).
You can use the library or have a look at the code - as this is open.
There is no direct way to read a File into a String.
But there is a quick alternative - read the File into a Byte array and convert it into a String.
Untested:
File f = new File("/foo/bar");
InputStream fStream = new FileInputStream(f);
ByteArrayOutputStream bStream = new ByteArrayOutputStream();
for(int data = fStream.read(); data > -1; data = fStream.read()) {
b.write(data);
}
String theResult = new String(bStream.toByteArray(), "UTF-8");

Using an InputStream for Logging and then XML parsing

What I want to do is log the output from an inputstream that I go using
org.apache.http.HttpEntity entity = response.getEntity();
org.apache.http.HttpResponse content =entity.getContent();
//Print the result to the screen for debugging
//puroposes
if(Logging.DEBUG) {
InputStream content =entity.getContent();
int i;
StringBuilder b = new StringBuilder();
while( (i=content.read()) != -1 ) {
b.append((char)i);
}
Log.d(TAG, b.toString());
}
Now after I have finished logging, I want to use the exact same stream through an XML parser. The problem is that it tells me that the steam has already been used.
I tried to the use mark() and reset() calls before and after debugging but it didn't work.
It depends whether the inputstream that is returned supports it. The default implementation in the InputStream class does nothing, as described in the API. So you can't be sure whether the returned Stream actually supports it. To be sure of this, you should wrap it in a BufferedInputStream, which does supports these methods.
In general mark() and reset() won't work on an arbitrary InputStream. They only work on subclasses like FileInputStream where the underlying data source supports these operations.
For something like a SocketInputStream or a console InputStream, your only option will be to read and buffer the entire stream contents somewhere; e.g. in memory or by writing it to a temporary file.

Open InputStream as Reader

Can I easily convert InputStream to BufferedReader using Guava?
I'm looking for something like:
InputStream inputStream = ...;
BufferedReader br = Streams.newBufferedReader(inputStream);
I can open files using the Files.newReader(File file, Charset charset). That's cool and I want to do the same using the InputStream.
UPDATE:
Using CharStreams.newReaderSupplier seems to verbose for me. Correct me if I'm wrong, but in order to easily convert InputStream to BufferedReader using Guava I have to do something like that:
final InputStream inputStream = new FileInputStream("/etc/fstab");
Reader bufferedReader = new BufferedReader(CharStreams.newReaderSupplier(new InputSupplier<InputStream>(){
public InputStream getInput() throws IOException {
return inputStream;
}
}, Charset.defaultCharset()).getInput());
Of course I can create helper do sth like:
return new BufferedReader(new InputStreamReader(inputStream));
However I think that such helper should be offered by Guava IO. I can do such trick for File instance. Why cannot I for InputStream?
// Guava can do this
Reader r = Files.newReader(new File("foo"), charset);
// but cannot do this
Reader r = SomeGuavaUtil.newReader(inputStream, charset);
Correct me If I'm wrong but it seems to me like lack in the API.
No, there isn't anything quite like that in Guava. CharStreams is the general class for working with Readers and Writers and it has a method
InputSupplier<InputStreamReader> newReaderSupplier(
InputSupplier<? extends InputStream> in, Charset charset)
which could be useful with any kind of supplier of InputStreams.
Obviously, you can just write new BufferedReader(new InputStreamReader(in, charset)) or wrap that in your own factory method as well.
Edit:
Yes, you wouldn't want to use the InputSupplier version when you already have an InputStream. It's sort of like how it's a bad idea to make an Iterable that can actually only work once, such as one that wraps an existing Iterator or Enumeration or some such. In general, using InputSupplier requires thinking about how you do I/O a little different, such as thinking of a File as something that can act as a supplier of FileInputStreams. I've used InputSuppliers that wrap whole requests to a server and return the response content as an InputStream, enabling me to use Guava utilities to copy that to a file, etc.
In any case, I'm not entirely sure why CharStreams doesn't have a method to create a Reader from an InputStream other than perhaps they didn't feel it was needed. You may want to file an issue requesting this.

Categories

Resources