为什么这里的BufferedWriter最后关闭了也没有写入文件呢?

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

所以我写了这个 class 在 "for" 循环中将字符串写入文件,但是我无法使用 [=51] 中的 BufferedWriter 或 PrintWriter 将字符串内容写入文件=].该文件在本地目录中创建,但没有任何内容写入该文件。似乎是什么引起了这里的麻烦?

密码是,

package pmidtomeshConverter;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

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;

public class Convert2MeSH {

    public static void main(String[] args) throws JSONException, IOException, ParserConfigurationException, SAXException, TransformerException {


    BufferedWriter writer = new BufferedWriter(new FileWriter("pathToALocalDirectory/pmidMESH.txt", true));
    writer.write("at least this writes"); // This does not write either


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

        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));
        writer.append(indPMID + ":" + String.join("\t", list_MeSH)); // This does not write to the file either

    }

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

}

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

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

所以我想出了一个比较绕的方案。我知道 for 循环中的任何内容都没有写入文件,我不知道为什么没有将内容附加到文件中。

解决方案:首先,在循环中,我将内容写入一个Hashmap,然后在for循环外使用序列化将Hashmap写入文件。它工作得很好。

这是代码,

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 content gets written to the file. Each line in the file contains a unique Pubmed ID attached to the MeSH terms of the article