Bufferedwriter Not Writing Everything to Its Output File

BufferedWriter not writing everything to its output file

You need to close your OutputStream which will flush the remainder of your data:

out.close();

The default buffer size for BufferedWriter is 8192 characters, large enough to easily hold hundreds of lines of unwritten data.

Why is BufferedWriter not writing to file?

Call bWriter.flush() when you want your data to actually be flushed to your file on disk.
Or just call bWriter.close() when you're done working with your writer.
The bWriter.close() call will call bWriter.flush() internally.

BufferedWriter not writing entire file - only some of it

Close the BufferedWriter object.

writer.close();

It will not write your file unless you close an object of BufferedWriter.

Why BufferedWriter here is not writing to the file even though I close it in the end?

So I have worked out quite a detour solution. I understand that anything in the for-loop wasn't getting written in the file, and I have no idea why the content was not appended to the file.

The solution: First, in the loop, I write the content to a Hashmap and then outside the for-loop write the Hashmap to the file using serialization. It worked perfectly fine.

Here is the code,

package pmidtomeshConverter;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.XML;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;

public class Convert2MeSH {

public static void main(String[] args) {


//BufferedWriter writer = new BufferedWriter(new FileWriter("/home/anjani/eclipse-workspace/pmidtomeshConverter/src/main/resources/outputFiles/pmidMESH.txt", true));

//Universal Multimap to store the values
Map<String, String> universalMeSHMap = new HashMap<String, String>();

FileOutputStream fs;
BufferedWriter writer;
try {

fs = new FileOutputStream("/home/anjani/eclipse-workspace/pmidtomeshConverter/src/main/resources/outputFiles/pmidMESH.txt");
OutputStreamWriter ow = new OutputStreamWriter(fs);
writer = new BufferedWriter(ow);

JSONObject jsonPMIDlist = readJsonFromUrl("https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&retmode=json&retmax=1000&term=Physiotherapy%5d+OR+Rehabilitation");
JSONArray pmids = new JSONArray();
pmids = jsonPMIDlist.getJSONObject("esearchresult").getJSONArray("idlist");

for(int i=0; i<pmids.length();i++){

String baseURL = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&retmode=xml&rettype=abstract&id=";
String indPMID = pmids.get(i).toString();

Document doc = parseXML(new URL(baseURL + indPMID));

// Converts xml from doc into a string
String xmlString = xml2String(doc);

// Converts the xml-string into JSON
JSONObject jsonWithMeSH = XML.toJSONObject(xmlString);

JSONObject ind_MeSH = jsonWithMeSH.getJSONObject("PubmedArticleSet").getJSONObject("PubmedArticle").getJSONObject("MedlineCitation");

List<String> list_MeSH = new ArrayList<String>();
if (ind_MeSH.has("MeshHeadingList")) {

for (int j = 0; j < ind_MeSH.getJSONObject("MeshHeadingList").getJSONArray("MeshHeading").length(); j++) {

list_MeSH.add(ind_MeSH.getJSONObject("MeshHeadingList").getJSONArray("MeshHeading").getJSONObject(j).getJSONObject("DescriptorName").get("content").toString());
}

} else {

list_MeSH.add("null");

}

System.out.println(indPMID + ":" + String.join("\t", list_MeSH));

// instead of writing to a file, the content is stored in a HashMap
universalMeSHMap.put(indPMID, String.join("\t", list_MeSH));

}

// Writing the HashMap to the file (This is the answer)
for (Map.Entry<String,String> entry : universalMeSHMap.entrySet()) {

writer.append(entry.getKey() + ":" + entry.getValue() + "\n");

}

writer.flush();
writer.close();

} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

private static String xml2String(Document doc) throws TransformerException {

TransformerFactory transfac = TransformerFactory.newInstance();
Transformer trans = transfac.newTransformer();
trans.setOutputProperty(OutputKeys.METHOD, "xml");
trans.setOutputProperty(OutputKeys.INDENT, "yes");
trans.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", Integer.toString(2));

StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
DOMSource source = new DOMSource(doc.getDocumentElement());

trans.transform(source, result);
String xmlString = sw.toString();
return xmlString;

}

private static Document parseXML(URL url) throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse((url).openStream());
doc.getDocumentElement().normalize();
return doc;
}

private static String readAll(Reader rd) throws IOException {
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
return sb.toString();
}

public static JSONObject readJsonFromUrl(String url) throws IOException, JSONException {
InputStream is = new URL(url).openStream();
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
String jsonText = readAll(rd);
JSONObject json = new JSONObject(jsonText);
return json;
} finally {
is.close();
}
}}

The result file looks this way,

The content gets written to the file. Each line in the file contains a unique Pubmed ID attached to the MeSH terms of the article

Buffered writer not writing to file

Almost every time I have seen someone complain about BufferedWriter or PrintWriter not writing, it is always because of not flushing.

Important Rule: Always bw.close() Input/Output streams.

bw.close();

Other things you can consider depending on the need:

  1. (Generally not recommended) Enable autoflush when creating BufferedReader:
    It will be useful in cases like when writing to sockets and you expect a real time communication. Not generally useful when writing to files.
    bw = new BufferedWriter(fileWriter, true /* autoflush */);
  2. bw.flush(); whenever you think it is appropriate to actually write to disk.

BufferedWriter won't write all of the data to a file

I don't see you calling out.close(); anywhere. This will flush and close the underlying stream for you. I would put it right after your for-loop.

Always make sure you close your streams, otherwise some of your data might be hanging out in memory waiting for the JVM to come along and flush it out to your file.

Why BufferedWriter is writing the data into the file partially?

The data that you're writing in to an output stream isn't guaranteed to reach its destination immediately.

The BufferedWritter is a so-called high-level stream which decorates the underlying stream that deals with a particular destination of data like FileWriter (and there could be a few more streams in between them) by buffering the text output and providing a convince-method newLine().

BufferedWritter maintains a buffer (an array of characters) with a default size of 8192. And when it gets full, it hands it out to the underlying low-level stream. In this case, to a FileWriter, which will take care of encoding the characters into bytes.

When it's done, the JVM will hand the data out to the operating system via FileOutputStream (because under the hood character streams are build on top of bite streams).

So, the data written to the buffer will appear in a file in chunks:

  • when the buffer gets full;
  • and after the stream was closed.

Javadoc for method close() says:

Closes the stream, flushing it first.

I.e. before releasing the resource close() invokes method flush() which forces the cached data to be passed into its destination.

If no exception occur, everything that was written into the stream is guaranteed to reach the destination when the stream is being closed.

You can also use flush() in your code. But it has to applied with great caution. Probably when you deal with large amounts of critical data and which is useful, even when partially written (so in case of exceptions you'll lose less information). Misusing the flush() could significantly reduce the performance.

BufferedWriter NOT writing to .txt file [JAVA]

You never call flush or close on the instance of BufferedWriter, in fact, you ignore it completely. Also, you resource management is none existent. If you open a resource, you should close it.

For example...

FileReader file = new FileReader("client-temp.txt");
try (BufferedReader tc = new BufferedReader(file)) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter("datastore.txt"))) {

String line;

while ((line = tc.readLine()) != null)
{
String[] data = line.split(",");
String sensortype = data[0];
String date = data[1];
String time = data[2];
String reading = data[3];

String newdata = sensortype + date + time + reading;
System.out.println(line);

if (line != null)
{
bw.write(line);
bw.newLine();
}

System.out.println("Data sent to file");
}
} catch (IOException exp) {
exp.printStackTrace();
}
} catch (IOException exp) {
exp.printStackTrace();
}

See The try-with-resources Statement for more details

(ps: You can compound the try-with-resource statement, opening multiple resources within the same try (...) { section, but I wanted to demonstrate the basic concept)

Buffered Writer .write not writing to file

You are selecting a location to put a file here

File file = DirectoryChooser.showDialog(fxcontroller.getPrimaryStage());

And you are writing into a File that is one folder outside the Eclipse project (in case that wasn't clear)

File defaultMusicPath = new File("../defaultMusicPath.txt");
bw = new BufferedWriter(new FileWriter(defaultMusicPath,true));

Then you're writing the path of the first File object to the second File object correctly

bw.write(file.getAbsolutePath());

And if there are no errors, then you are writing to a file, so perhaps you are needing to close and reopen the file in your editor.

Remove the relative ../ if you want to write into the Eclipse project.

Also, I'd recommend closing the writer in a finally block after the catch. Or using try-with-resources like so

File f = new File("defaultMusicPath.txt");
try (BufferedWriter bw =
Files.newBufferedWriter(Paths.get(f.toURI()), StandardOpenOption.APPEND);
PrintWriter out = new PrintWriter(bw)) {
out.println("Hello, world!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


Related Topics



Leave a reply



Submit