Java String from InputStream [duplicate] - java

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
How do I convert an InputStream to a String in Java?
In Java how do a read an input stream in to a string?
I have an InputSteam and need to simply get a single simple String with the complete contents.
How is this done in Java?

Here is a modification of Gopi's answer that doesn't have the line ending problem and is also more effective as it doesn't need temporary String objects for every line and avoids the redundant copying in BufferedReader and the extra work in readLine().
public static String convertStreamToString( InputStream is, String ecoding ) throws IOException
{
StringBuilder sb = new StringBuilder( Math.max( 16, is.available() ) );
char[] tmp = new char[ 4096 ];
try {
InputStreamReader reader = new InputStreamReader( is, ecoding );
for( int cnt; ( cnt = reader.read( tmp ) ) > 0; )
sb.append( tmp, 0, cnt );
} finally {
is.close();
}
return sb.toString();
}

You need to construct an InputStreamReader to wrap the input stream, converting between binary data and text. Specify the appropriate encoding based on your input source.
Once you've got an InputStreamReader, you could create a BufferedReader and read the contents line by line, or just read buffer-by-buffer and append to a StringBuilder until the read() call returns -1.
The Guava library makes the second part of this easy - use CharStreams.toString(inputStreamReader).

Here is an example code adapted from here.
public String convertStreamToString(InputStream is) throws IOException {
/*
* To convert the InputStream to String we use the BufferedReader.readLine()
* method. We iterate until the BufferedReader return null which means
* there's no more data to read. Each line will appended to a StringBuilder
* and returned as String.
*/
if (is != null) {
StringBuilder sb = new StringBuilder();
String line;
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
} finally {
is.close();
}
return sb.toString();
} else {
return "";
}
}

You can also use Apache Commons IO library
Specifically, you can use IOUtils#toString(InputStream inputStream) method

You could also use a StringWriter as follows; each read from your InputStream is matched with a write (or append) to the StringWriter, and upon completion you can call getBuffer to get a StringBuffer which could be used directly or you could get call its toString method.

Wrap the Stream in a Reader to get locale conversion, and then keep reading while collecting in a StringBuffer. When done, do a toString() on the StringBuffer.

Related

Java copy entire file without the double quotes

I have a method to copy the entire file from one destination to another destination using buffer:
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
The file is in csv format:
"2280B_TJ1400_001","TJ1400_Type-7SR","192.168.50.76","Aries SDH","6.0","192.168.0.254",24,"2280B Cyberjaya","Mahadzir Ibrahim"
But as you can see it has quotes inside it. Is it possible remove them by based on my exisitng code???
Output should be like this:
2280B_TJ1400_001,TJ1400_Type-7SR,192.168.50.76,Aries SDH,6.0,192.168.0.254,24,2280B Cyberjaya,Mahadzir Ibrahim
If you use a BufferedReader you can use the readLine() function to read the contents of the file as a String. Then you can use the normal functions on String to manipulate it before writing it to the output. By using an OutputStreamWriter you can write the Strings directly.
An advantage of the above is that you never have to bother with the raw bytes, this makes your code easier to read and less prone to mistakes in special cases.
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(src)));
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(dest));
String line;
while ((line = in.readLine()) != null) {
String stringOut = line.replaceAll("\"", "");
out.write(stringOut);
}
in.close();
out.close();
Note that this removes all " characters, not just the ones at the start and end of each String. To do that, you can use a StringTokenizer, or a more complex replace.
Not sure it's a good idea or not, but you can do something like :
while ((len = in.read(buf)) > 0) {
String temp = new String(buf);
temp = temp.replaceAll("\"","");
buf = temp.getBytes();
len = temp.length();
out.write(buf, 0, len);
}
For me, I would read all the file before, in a String, and then strip out the ' " ' in the string. Then write it to the dest file.
Read the file in a string
I found this simple solution. This may not be the best depending on your level of error catching you need.But it's working enough ;)
String content = new Scanner(new File("filename")).useDelimiter("\\Z").next();
Stripout the ' " '
content = content.replaceAll('"', "");
Write it to dest file from here
Files.write(Paths.get("./duke.txt"), msg.getBytes());
This is for java 7+.
Did not test it but it should work !
Not necessarily good style, filtering quotes in binary data, but very solid.
Wrap the original InputStream with your own InputStream, filtering out the double quote.
I have added a quirk: in MS Excel a quoted field may contain a quote, which then is self-escaped, represented as two double quotes.
InputStream in = new UnquotingInputStream(new FileInputStream(src));
/**
* Removes ASCII double quote from an InputStream.
* Two consequtive quotes stand for one quote: self-escaping like used
* by MS Excel.
*/
public class UnquotingInputStream extends InputStream {
private final InputStream in;
private boolean justHadAQuote;
public UnquotingInputStream(InputStream in) {
this.in = in;
}
#Override
public int read() throws IOException {
int c = in.read();
if (c == '\"') {
if (!justHadAQuote) {
justHadAQuote = true;
return read(); // Skip quote
}
}
justHadAQuote = false;
return c;
}
}
Works for all encodings that use ASCII as subset. So not: UTF-16 or EBCDIC.

Faster input style in java

Scanner has a method hasNext() but if i want to use BufferedReader insteadOf Scanner how to handle hasNext() types of method in BufferedReader?
I want to do this because BufferedReader is faster than Scanner. Is there any faster input reading way besides BufferedReader?
Need Help! Thanks in advance.
If you are working with Strings use a StringBuilder. It is a built in object in Java and allows you to not have to recreate a String every time you append a String.
I have not worked with a scanner much because I like BufferedReader so much. Java's BufferedReader reads a certain amount of bytes at a time. The default buffer size is 8192 characters. You can change this is you want to if you think you will be reading enormous amounts of characters. An integer as the second parameter would specify the number of bytes to read each time.
This is how you would use a BufferedReader and StringBuilder efficiently:
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
String output;
try(BufferedReader reader = new BufferedReader(new FileReader(System.getProperty("user.home") + "/Desktop/lotsOfText.txt"), 8192)) { //if you want a bigger buffer - give it a larger number
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n"); //StringBuilder returns a reference to itself
}
} catch (IOException io) {
System.err.println(io.toString());
}
output = sb.toString();
System.out.println(output);
}
If you are expecting double or ints, you can use a try{}catch (Exception e){} and in the try use either java's class Double or Integer to parse a string:
try {
double d = Double.parse(line);
int i = Integer.parse(line);
catch (NumberFormatException nfe) {
System.err.println(nfe.toString() + "\n\nThe number was unreadable");
}
Your question was really vague, so it is hard to give you an explicit answer. I hope this helps.
Also, as a note, BufferedReader also accepts an InputStreamReader as an argument, so you could have
try(BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)) {} catch...
in order to read user input.
The "truly" correct way to read an InputStream can be found here

Java file not written to stream with new line characters

We're streaming a CSV file from a web service. It appears that we're losing the new line characters when streaming - the client gets the file all on a single line. Any idea what we're doing wrong?
Code:
public static void writeFile(OutputStream out, File file) throws IOException {
BufferedReader input = new BufferedReader(new FileReader(file)); //File input stream
String line;
while ((line = input.readLine()) != null) { //Read file
out.write(line.getBytes()); //Write to output stream
out.flush();
}
input.close();
}
Don't use BufferedReader. You already have an OutputStream at hands, so just get an InputStream of the file and pipe the bytes from input to output it the usual Java IO way. This way you also don't need to worry about newlines being eaten by BufferedReader:
public static void writeFile(OutputStream output, File file) throws IOException {
InputStream input = null;
byte[] buffer = new byte[10240]; // 10KB.
try {
input = new FileInputStream(file);
for (int length = 0; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
} finally {
if (input != null) try { input.close(); } catch (IOException logOrIgnore) {}
}
}
Using a Reader/Writer would involve character encoding problems if you don't know/specify the encoding beforehand. You actually also don't need to know about them here. So just leave it aside.
To improve performance a bit more, you can always wrap the InputStream and OutputStream in an BufferedInputStream and BufferedOutputStream respectively.
The readline method uses the newline chars to delimit what gets read, so the newlines themselves are not returned by readLine.
Don't use readline, you can use a BufferedInputStream and read the file one byte at a time if you want, or pass your own buffer into OutputStream.write.
Note that, like BalusC and Michael Borgwardt say, Readers and Writers are for text, if you just want to copy the file you should use InputStream and OutputStream, you are only concerned with bytes.
There are several things wrong with that code. It may also mutilate any NON-ASCII text since it converts via the platform default encoding twice - and for no good reason at all.
Don't use a Reader to read the file, use a FileInputStream and transfer bytes, avoiding the unnecessary and potentially destructive charset conversions. The line break problem will also be gone.
Any idea what we're doing wrong?
Yes. This line drops the "new line character"
while ((line = input.readLine()) != null) {
And then you write it without it:
out.write(line.getBytes());
This this related question.
BufferedReader.ReadLine() does not preserve the newline. Thus you'll have to add it when writing it out
You can use a PrintWriter which offers a prinln() method. This will also save you from converting the string into an array of chars.
public static void writeFile(OutputStream o, File file) throws IOException {
PrintWriter out = new PrintWriter(new OutputStreamWriter(o));
BufferedReader input = new BufferedReader(new FileReader(file)); //File input stream
String line;
while ((line = input.readLine()) != null) { //Read file
out.println(line); //Write to output stream
out.flush();
}
input.close();
}

How do I read input character-by-character in Java?

I am used to the c-style getchar(), but it seems like there is nothing comparable for java. I am building a lexical analyzer, and I need to read in the input character by character.
I know I can use the scanner to scan in a token or line and parse through the token char-by-char, but that seems unwieldy for strings spanning multiple lines. Is there a way to just get the next character from the input buffer in Java, or should I just plug away with the Scanner class?
The input is a file, not the keyboard.
Use Reader.read(). A return value of -1 means end of stream; else, cast to char.
This code reads character data from a list of file arguments:
public class CharacterHandler {
//Java 7 source level
public static void main(String[] args) throws IOException {
// replace this with a known encoding if possible
Charset encoding = Charset.defaultCharset();
for (String filename : args) {
File file = new File(filename);
handleFile(file, encoding);
}
}
private static void handleFile(File file, Charset encoding)
throws IOException {
try (InputStream in = new FileInputStream(file);
Reader reader = new InputStreamReader(in, encoding);
// buffer for efficiency
Reader buffer = new BufferedReader(reader)) {
handleCharacters(buffer);
}
}
private static void handleCharacters(Reader reader)
throws IOException {
int r;
while ((r = reader.read()) != -1) {
char ch = (char) r;
System.out.println("Do something with " + ch);
}
}
}
The bad thing about the above code is that it uses the system's default character set. Wherever possible, prefer a known encoding (ideally, a Unicode encoding if you have a choice). See the Charset class for more. (If you feel masochistic, you can read this guide to character encoding.)
(One thing you might want to look out for are supplementary Unicode characters - those that require two char values to store. See the Character class for more details; this is an edge case that probably won't apply to homework.)
Combining the recommendations from others for specifying a character encoding and buffering the input, here's what I think is a pretty complete answer.
Assuming you have a File object representing the file you want to read:
BufferedReader reader = new BufferedReader(
new InputStreamReader(
new FileInputStream(file),
Charset.forName("UTF-8")));
int c;
while((c = reader.read()) != -1) {
char character = (char) c;
// Do something with your character
}
Another option is to not read things in character by character -- read the entire file into memory. This is useful if you need to look at the characters more than once. One trivial way to do that is:
/** Read the contents of a file into a string buffer */
public static void readFile(File file, StringBuffer buf)
throws IOException
{
FileReader fr = null;
try {
fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
char[] cbuf = new char[(int) file.length()];
br.read(cbuf);
buf.append(cbuf);
br.close();
}
finally {
if (fr != null) {
fr.close();
}
}
}
Wrap your input stream in a buffered reader then use the read method to read one byte at a time until the end of stream.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Reader {
public static void main(String[] args) throws IOException {
BufferedReader buffer = new BufferedReader(
new InputStreamReader(System.in));
int c = 0;
while((c = buffer.read()) != -1) {
char character = (char) c;
System.out.println(character);
}
}
}
If I were you I'd just use a scanner and use ".nextByte()". You can cast that to a char and you're good.
You have several options if you use BufferedReader. This buffered reader is faster than Reader so you can wrap it.
BufferedReader reader = new BufferedReader(new FileReader(path));
reader.read(char[] buffer);
this reads line into char array. You have similar options. Look at documentation.
Wrap your reader in a BufferedReader, which maintains a buffer allowing for much faster reads overall. You can then use read() to read a single character (which you'll need to cast). You can also use readLine() to fetch an entire line and then break that into individual characters. The BufferedReader also supports marking and returning, so if you need to, you can read a line multiple times.
Generally speaking, you want to use a BufferedReader or BufferedInputStream
on top of whatever stream you are actually using since the buffer they maintain will make multiple reads much faster.
In java 5 new feature added that is Scanner method who gives the chance to read input character by character in java.
for instance;
for use Scanner method import java.util.Scanner;
after in main method:define
Scanner myScanner = new Scanner(System.in);
//for read character
char anything=myScanner.findInLine(".").charAt(0);
you anything store single character, if you want more read more character declare more object like anything1,anything2...
more example for your answer please check in your hand(copy/paste)
import java.util.Scanner;
class ReverseWord {
public static void main(String args[]){
Scanner myScanner=new Scanner(System.in);
char c1,c2,c3,c4;
c1 = myScanner.findInLine(".").charAt(0);
c2 = myScanner.findInLine(".").charAt(0);
c3 = myScanner.findInLine(".").charAt(0);
c4 = myScanner.findInLine(".").charAt(0);
System.out.print(c4);
System.out.print(c3);
System.out.print(c2);
System.out.print(c1);
System.out.println();
}
}
This will print 1 character per line from the file.
try {
FileInputStream inputStream = new FileInputStream(theFile);
while (inputStream.available() > 0) {
inputData = inputStream.read();
System.out.println((char) inputData);
}
inputStream.close();
} catch (IOException ioe) {
System.out.println("Trouble reading from the file: " + ioe.getMessage());
}

Most concise way to read the contents of a file/input stream in Java?

What ist most concise way to read the contents of a file or input stream in Java? Do I always have to create a buffer, read (at most) line by line and so on or is there a more concise way? I wish I could do just
String content = new File("test.txt").readFully();
Use the Apache Commons IOUtils package. In particular the IOUtils class provides a set of methods to read from streams, readers etc. and handle all the exceptions etc.
e.g.
InputStream is = ...
String contents = IOUtils.toString(is);
// or
List lines = IOUtils.readLines(is)
I think using a Scanner is quite OK with regards to conciseness of Java on-board tools:
Scanner s = new Scanner(new File("file"));
StringBuilder builder = new StringBuilder();
while(s.hasNextLine()) builder.append(s.nextLine());
Also, it's quite flexible, too (e.g. regular expressions support, number parsing).
Helper functions. I basically use a few of them, depending on the situation
cat method that pipes an InputStream to an OutputStream
method that calls cat to a ByteArrayOutputStream and extracts the byte array, enabling quick read of an entire file to a byte array
Implementation of Iterator<String> that is constructed using a Reader; it wraps it in a BufferedReader and readLine's on next()
...
Either roll your own or use something out of commons-io or your preferred utility library.
To give an example of such an helper function:
String[] lines = NioUtils.readInFile(componentxml);
The key is to try to close the BufferedReader even if an IOException is thrown.
/**
* Read lines in a file. <br />
* File must exist
* #param f file to be read
* #return array of lines, empty if file empty
* #throws IOException if prb during access or closing of the file
*/
public static String[] readInFile(final File f) throws IOException
{
final ArrayList lines = new ArrayList();
IOException anioe = null;
BufferedReader br = null;
try
{
br = new BufferedReader(new FileReader(f));
String line;
line = br.readLine();
while(line != null)
{
lines.add(line);
line = br.readLine();
}
br.close();
br = null;
}
catch (final IOException e)
{
anioe = e;
}
finally
{
if(br != null)
{
try {
br.close();
} catch (final IOException e) {
anioe = e;
}
}
if(anioe != null)
{
throw anioe;
}
}
final String[] myStrings = new String[lines.size()];
//myStrings = lines.toArray(myStrings);
System.arraycopy(lines.toArray(), 0, myStrings, 0, lines.size());
return myStrings;
}
(if you just want a String, change the function to append each lines to a StringBuffer (or StringBuilder in java5 or 6)
String content = (new RandomAccessFile(new File("test.txt"))).readUTF();
Unfortunately Java is very picky about the source file being valid UTF8 though, or you will get an EOFException or UTFDataFormatException.
You have to create your own function, I suppose. The problem is that Java's read routines (those I know, at least) usually take a buffer argument with a given length.
A solution I saw is to get the size of the file, create a buffer of this size and read the file at once. Hoping the file isn't a gigabyte log or XML file...
The usual way is to have a fixed size buffer or to use readLine and concatenate the results in a StringBuffer/StringBuilder.
I don't think reading using BufferedReader is a good idea because BufferedReader will return just the content of line without the delimeter. When the line contains nothing but newline character, BR will return a null although it still doesn't reach the end of the stream.
String org.apache.commons.io.FileUtils.readFileToString(File file)
Pick one from here.
How do I create a Java string from the contents of a file?
The favorite was:
private static String readFile(String path) throws IOException {
FileInputStream stream = new FileInputStream(new File(path));
try {
FileChannel fc = stream.getChannel();
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
/* Instead of using default, pass in a decoder. */
return CharSet.defaultCharset().decode(bb).toString();
}
finally {
stream.close();
}
}
Posted by erickson
Or the Java 8 way:
try {
String str = new String(Files.readAllBytes(Paths.get("myfile.txt")));
...
} catch (IOException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
}
One may pass an appropriate Charset to the String constructor.

Categories

Resources