Issue with String Buffer in java - java

I have a servlet in which the from InputStream I am getting the my form data in XML format. I am able to get retrieve the form data in XML format and able to write the same in file. If I open the file I am able to see my form data.
Now the issue is, When i try to append the form data to the string buffer it is not happening. I tried buffer.append(). After that method When I try to print the string buffer value nothing is showing/printing in the console.
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("html/text");
PrintWriter out = response.getWriter();
out.println("doPost Method is excecuting");
DataInputStream in = new DataInputStream (request.getInputStream());
StringBuffer buffer = new StringBuffer();
File file = new File("reqOutput.txt");
file.createNewFile();
FileWriter writer = new FileWriter(file);
int value;
while ((value=in.read()) != -1) {
buffer.append(value);
writer.write(value);
}
System.out.println("Value is : "+ buffer.toString()); // Nothing is printing
writer.flush();
writer.close();
}
What's wrong with my code.Any suggestions please.

Here is your code modified to read from a file:
public static void main(final String[] args) throws Exception {
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader("test"));
final StringBuilder sb = new StringBuilder();
String line;
while ((line = in.readLine()) != null) {
sb.append(line);
}
System.out.println("Value is : " + sb.toString());
} finally {
if (in != null) {
in.close();
}
}
}
I added a BufferedReader around the FileReader to optimize the reading.
I switched from reading one character at a time to reading line by line.
This also gives you the results as String so you don't have to convert the int.
Furthermore I added resource handling (pre-7 style and without exception handling) and switched to StringBuilder.
Output:
hello world! -> Value is : hello world!
I think there is another problem, not in this part of your code.
Additional comments on your code (not related to the question):
StringBuffer is a thread-safe implementation. If you have no need for this (like in your servlet example) you'd better use StringBuilder.
Don't close resources within the code block, use a try-finally (or since Java 7 try-with-resources) to guarantee resources are always closed, even when exceptions occur in the block somewhere.

Related

read from file and write some parts in another file

I have to read from a text file and format the input. I'm new to java reading from files, and I don't know how to work with just some parts of what I read
Here is the initial file: http://pastebin.com/D0paWtAd
And I have to write in another file the following output:
Average,Joe,44,31,18,12,9,10
I've managed just to take everything from the file and print it to output. I would need help just in taking the output I need and print it to the screen. Any help is appreciated.
This is what I wrote up to now:
public class FileParsing {
public static String
read(String filename) throws IOException {
BufferedReader in = new BufferedReader(new FileReader("C:\\Users\\Bogdi\\Desktop\\example.txt"));
String s;
StringBuilder sb = new StringBuilder();
while((s = in.readLine())!= null) sb.append(s + "\n");
in.close();
return sb.toString();
}
If your goal is to do the specified output in another file you don't need to first get the content of your file in a StringBuilder before processing it, you can append the processed datas directly in a StringBuilder then you can write the result in a file. Here is an example that would work for the given file but you may have to modify it if the keys change in the future:
The following method will correctly process the datas from your file
public static String read(String filename) throws IOException {
BufferedReader in = new BufferedReader(new FileReader(filename));
String s;
StringBuilder sb = new StringBuilder();
while((s = in.readLine())!= null) {
String[] split1 = s.split("=");
if (split1[0].equals("name")) {
StringTokenizer tokenizer = new StringTokenizer(split1[1]);
sb.append(tokenizer.nextToken());
sb.append(",");
sb.append(tokenizer.nextToken());
sb.append(",");
} else if (split1[0].equals("index")) {
sb.append(split1[1] + ",");
} else if (split1[0].equals("FBid")) {
sb.append(split1[1]);
} else {
StringTokenizer tokenizer = new StringTokenizer(split1[1]);
String wasted = tokenizer.nextToken();
sb.append(tokenizer.nextToken() + ",");
}
}
in.close();
return sb.toString();
}
The next method will read any string to a file
public static void writeStringToFile(String string, String filePath) throws IOException {
BufferedWriter writer = new BufferedWriter(
new FileWriter(
new File(filePath)
)
);
writer.write(string);
writer.newLine();
writer.flush();
writer.close();
}
And here is a simple tests (File1.txt contains the datas from the file you shared on paste bin and I write them in another file)
public static void main(String[] args) throws Exception {
String datas = read("C:\\Tests\\File1.txt");
System.out.println(datas);
writeStringToFile(datas, "C:\\Tests\\FileOuput.txt" );
}
It will produce the exact output that you are expecting
[EDIT] #idk, apparently you have an exception executing my example, while it is working fine for me. That could only mean there is an error at data level. Here is the data sample that I used (and I believe I exactly copy the datas you shared)
And here is the result:
Good to know you are using "StringBuilder" component instead being concatenating your String values, way to go :).
More than knowledge on the Java.IO API to work with files, you will need some logic to get the results you expect. Here I came with an approach that could help you, not perfect, but can point you on how to face this problem.
//Reference to your file
String myFilePath = "c:/dev/myFile.txt";
File myFile = new File(myFilePath);
//Create a buffered reader, which is a good start
BufferedReader breader = new BufferedReader(new FileReader(myFile));
//Define this variable called line that will evaluate each line of our file
String line = null;
//I will use a StringBuilder to append the information I need
StringBuilder appender = new StringBuilder();
while ((line = breader.readLine()) != null) {
//First, I will obtain the characters after "equals" sign
String afterEquals = line.substring(line.indexOf("=") + 1, line.length());
//Then, if it contains digits...
if (afterEquals.matches(".*\\d+.*")) {
//I will just get the digits from the line
afterEquals = afterEquals.replaceAll("\\D+","");
}
//Finally, append the contents
appender.append(afterEquals);
appender.append(",");//This is the comma you want to include
}
//I will delete the last comma
appender.deleteCharAt(appender.length() - 1);
//Close the reader...
breader.close();
//Then create a process to write the content
BufferedWriter myWriter = new BufferedWriter(new FileWriter(new File("myResultFile.txt")));
//Write the full contents I get from my appender :)
myWriter.write(appender.toString());
//Close the writer
myWriter.close();
}
Hope this can help you. Happy coding!

Java fileinput (read and write) to a file looping thru each line

I have this method that access a exisitng file, loop thru each line and replace (string to string) a certain line if the condition is met:
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.InputStreamReader;
private void UpdateConfig() {
try {
FileInputStream fstream = new FileInputStream("c:\\user\\config.properties");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
while ((strLine = br.readLine()) != null) {
if (strLine.contains("FTPDate=2014/07/01 00:59:00")) {
System.out.println("FILE " + strLine);
strLine.replace("FTPDate=2014/07/01 00:59:00", "FTPDate=2014/09/10 00:00:00");
//strLine.replace("((19|20)\\d\\d/(0?[1-9]|1[012])/(0?[1-9]|[12][0-9]|3[01])) ([2][0-3]|[0-1][0-9]|[1-9]):[0-5][0-9]:([0-5][0-9]|[6][0])", "2014/09/10 00:00:00");
System.out.println("FILE " + strLine);
}
}
in.close();
} catch (Exception e) {
}
}
In the sysout it seems its being replaced:
FILE FTPDateTejas=2014/07/01 00:59:00
FILE FTPDateTejas=2014/09/10 00:00:00
But when I check the file, the date still stays the same. Am I missing something? anyone knows what I missed out? thank you
When you are doing:
strLine = br.readLine() it loads the next line from the BufferedReader into memory. This means that you have your data on disk and in memory and that those two are not linked to each other in any way. When doing modifications on strLine I believe you have in your code:
strLine = strLine.replace("FTPDate=2014/07/01 00:59:00", "FTPDate=2014/09/10 00:00:00");
As replace doesn't modify the contents of the objects on which it is being called but returns a new String objects (Strings are immutable). So what that does it creates a new object but does not modify your on disk data (as I said, it's not linked to it any more!).
You could think "ok then how do I link those two and override the file in place?". Well Java does provide random file access as described in the doc but the only thing you can do with it is modify characters at a certain position, you cannot insert things in the middle. So what you would have to do is read the rest of your file, make your modification and then append that rest of the file, yes you need to shift things in case your new string with which you are substituting would be shorter/longer than what you are replacing.
That's why an easier solution would be to:
open a new file to write to
write line by line to it (the strings after the replace)
delete the old file and rename the new file
Without copying the file the code would look something like this:
private void UpdateConfig() {
File fstream = new File("c:\\user\\config.properties");
File file = new File("c:\\user\\config.properties-new");
try {
file.createNewFile();
} catch (IOException e) {
// handle
}
try (FileReader in = new FileReader(fstream);
FileWriter fw = new FileWriter(file.getAbsoluteFile())) {
try (BufferedReader br = new BufferedReader(in);
BufferedWriter bw = new BufferedWriter(fw)) {
String strLine;
while ((strLine = br.readLine()) != null) {
if (strLine.contains("FTPDate=2014/07/01 00:59:00")) {
System.out.println("FILE " + strLine);
strLine = strLine.replace("FTPDate=2014/07/01 00:59:00",
"FTPDate=2014/09/10 00:00:00");
//strLine.replace("((19|20)\\d\\d/(0?[1-9]|1[012])/(0?[1-9]|[12][0-9]|3[01])) ([2][0-3]|[0-1][0-9]|[1-9]):[0-5][0-9]:([0-5][0-9]|[6][0])", "2014/09/10 00:00:00");
bw.write(strLine);
System.out.println("FILE " + strLine);
}
}
}
// copy files here
} catch (IOException e) {
// handle
}
}
There might be some logical/syntactic problems as I was writing in in a plain text editor. I modified the code a bit to use Java 7's try-with-resources, which is a cleaner way of closing resources than what you were doing - in your code when an exception would be thrown the stream might not had been closed.

Building Java server and I can't get my page to stop loading (using PrintWriter and Buffered Reader)

I'm building a Java server and everything has been working as expected until now. I can serve up a static html page using two methods I wrote: body and header. Now, I am trying to write a new method called "bodywithQueryString".
Problem:
It almost works, but after the page is loaded, the loading won't stop. It just loads and loads. This is not happening with my static pages.
The only difference between the old method and new bodyWithQueryString() method is that in the new method I am using a buffered reader and print writer. These are new-ish functions for me so I'm guessing I'm not doing it right.
Here's how my new method is supposed to function:
I want to pass my route and querystring (queryarray) to bodyWithQueryString method. I want the method to read the file (from the route) to a byte output stream, do a replaceall on the key/value pair of the querystring while reading and, lastly, return the bytes. The getResponse() main method would then send the html to the browser.
Here's my code:
public void getResponse() throws Exception {
String[] routeParts = parseRoute(route); //break apart route and querystring
File theFile = new File(routeParts[0]);
if (theFile.canRead()) {
out.write(header( twoHundredStatusCode, routeParts[0], contentType(routeParts[0]) ) );
if (routeParts.length > 1) { //there must be a querystring
String[] queryStringArray = parseQueryString(routeParts[1]); //break apart querystring
out.write(bodyWithQueryString(routeParts[0], queryStringArray)); //use new body method
}
else out.write(body(routeParts[0])); //use original body method
out.flush();
private byte[] bodyWithQueryString(String route, String[] queryArray)
throws Exception {
BufferedReader reader = new BufferedReader(new FileReader(route));
ByteArrayOutputStream fileOut = new ByteArrayOutputStream();
PrintWriter writer = new PrintWriter(fileOut);
String line;
while ((line = reader.readLine()) != null) writer.println(line.replaceAll(queryArray[0] ,queryArray[1]));
writer.flush();
writer.close();
reader.close();
return fileOut.toByteArray();
}
It seems to me that you are not returning Content-Length header. This makes it hard for browser know when to stop loading the response.

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();
}

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