나는 XML 응답의 형태로 결과를 가져 오기 및 Java에서 파일의 내용의 일부를 작성하는 코드를 다음 썼다. 이것은 공공 데이터베이스에 700,000에 대한 쿼리에 대한 XML 응답을 수신하여 수행됩니다.
코드가 파일에 쓸 수 있습니다 전에 그러나,이 두 코드의 임의의 위치에서 (서버에서) 어떤 임의의 예외에 의해 중지됩니다. 나는 들어 루프 자체에서 파일에 쓰기 시도했지만 수 없습니다. 그래서 자바의 HashMap로받은 응답에서 덩어리를 저장하고 단일 통화에 파일에의 HashMap를 작성했습니다. 코드는 HashMap에 대한 루프 및 저장합니다 모든 응답을 수신하기 전에, 그것은 몇 가지를 제외하고 중지 (아마 1만5천번째 반복에서!). 하나는 데이터를 가져 오기 위해 이러한 반복을 필요로 자바에서 파일에 쓸 수있는 다른 효율적인 방법이 있습니까?
이 코드에 사용하는 로컬 파일은 여기 .
내 코드입니다
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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 random {
static FileWriter fileWriter;
static PrintWriter writer;
public static void main(String[] args) {
// Hashmap to store the MeSH values for each PMID
Map<String, String> universalMeSHMap = new HashMap<String, String>();
try {
// FileWriter for MeSH terms
fileWriter = new FileWriter("/home/user/eclipse-workspace/pmidtomeshConverter/src/main/resources/outputFiles/pmidMESH.txt", true);
writer = new PrintWriter(fileWriter);
// Read the PMIDS from this file
String filePath = "file_attached_to_Post.txt";
String line = null;
BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
String[] pmidsAll = null;
int x = 0;
try {
//print first 2 lines or all if file has less than 2 lines
while(((line = bufferedReader.readLine()) != null) && x < 1) {
pmidsAll = line.split(",");
x++;
}
}
finally {
bufferedReader.close();
}
// List of strings containing the PMIDs
List<String> pmidList = Arrays.asList(pmidsAll);
// Iterate through the list of PMIDs to fetch the XML files from PubMed using eUtilities API service from PubMed
for (int i = 0; i < pmidList.size(); i++) {
String baseURL = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&retmode=xml&rettype=abstract&id=";
// Process to get the PMIDs
String indPMID_p0 = pmidList.get(i).toString().replace("[", "");
String indPMID_p1 = indPMID_p0.replace("]", "");
String indPMID_p2 = indPMID_p1.replace("\\", "");
String indPMID_p3 = indPMID_p2.replace("\"", "");
// Fetch XML response from the eUtilities into a document object
Document doc = parseXML(new URL(baseURL + indPMID_p3));
// Convert the retrieved XMl into a Java String
String xmlString = xml2String(doc); // Converts xml from doc into a string
// Convert the Java String into a JSON Object
JSONObject jsonWithMeSH = XML.toJSONObject(xmlString); // Converts the xml-string into JSON
// -------------------------------------------------------------------
// Getting the MeSH terms from a JSON Object
// -------------------------------------------------------------------
JSONObject ind_MeSH = jsonWithMeSH.getJSONObject("PubmedArticleSet").getJSONObject("PubmedArticle").getJSONObject("MedlineCitation");
// List to store multiple MeSH types
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");
}
universalMeSHMap.put(indPMID_p3, String.join("\t", list_MeSH));
writer.write(indPMID_p3 + ":" + String.join("\t", list_MeSH) + "\n");
System.out.println("Completed iteration for " + i + " PMID");
}
// Write to the file here
for (Map.Entry<String,String> entry : universalMeSHMap.entrySet()) {
writer.append(entry.getKey() + ":" + entry.getValue() + "\n");
}
System.out.print("Completed writing the file");
} 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();
} finally {
writer.flush();
writer_pubtype.flush();
writer.close();
writer_pubtype.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();
}
}
}
이것은 예외 전에 콘솔에 인쇄하는 것입니다.
- 0 PMID에 대한 완료 반복
- 1 PMID에 대한 완료 반복
- 2 PMID에 대한 완료 반복
- 3 PMID에 대한 완료 반복
- 4 PMID에 대한 완료 반복
- 5 PMID에 대한 완료 반복
- 그리고 그것은 아래 예외가 나타날 때까지 기록 ...
그래서 루프에있는 임의의 시점에서, 나는 아래의 예외를 얻을.
java.io.FileNotFoundException : https://dtd.nlm.nih.gov/ncbi/pubmed/out/pubmed_190101.dtdsun.net.www.protocol에서 sun.net.www.protocol.http.HttpURLConnection.getInputStream (HttpURLConnection.java:1492)에서 sun.net.www.protocol.http.HttpURLConnection.getInputStream0 (HttpURLConnection.java:1890)에서 를 com.sun.org.apache.xerces.internal에서 com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity (XMLEntityManager.java:647)에서 .https.HttpsURLConnectionImpl.getInputStream (HttpsURLConnectionImpl.java:263) 를 com.sun.org.apache.xerces.internal에서 .impl.XMLEntityManager.startEntity com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity에서 (XMLEntityManager.java:1304) (XMLEntityManager.java:1270) com.sun.org.apache.xerces에서 .impl.XMLDTDScannerImpl.setInputSource com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl $ DTDDriver.dispatch에서 (XMLDTDScannerImpl.java:264) (XMLDocumentScannerImpl.java:1161) .internal.impl.com.sun.org.apache.xerces에서 com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl $ PrologDriver.next (XMLDocumentScannerImpl.java:959)에서 XMLDocumentScannerImpl $ DTDDriver.next (XMLDocumentScannerImpl.java:1045). internal.impl.XMLDocumentScannerImpl.next com.sun.org.apache.xerces에서 com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument (XMLDocumentFragmentScannerImpl.java:505)에서 (XMLDocumentScannerImpl.java:602). internal.parsers.XML11Configuration.parse com.sun.org.apache.xerces에서 com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse (XML11Configuration.java:771)에서 (XML11Configuration.java:842). internal.parsers.XMLParser.parse com.sun.org.apache.xerces에서 com.sun.org.apache.xerces.internal.parsers.DOMParser.parse (DOMParser.java:243)에서 (XMLParser.java:141). internal.jaxp.DocumentBuilderImpl.pmidtomeshConverter.Convert2MeSH.main에서 pmidtomeshConverter.Convert2MeSH.parseXML (Convert2MeSH.java:240)에서 javax.xml.parsers.DocumentBuilder.parse (DocumentBuilder.java:121)에서 파싱 (DocumentBuilderImpl.java:339) (Convert2MeSH.java:121 )
지도를 사용할 필요가 없습니다; 바로 파일을 직접 작성합니다. 더 나은 성능을 사용하는 경우 a BufferedWriter
.
나는 또한 어떤 속도 제한 또는 서버 측에서 그 성격의 아무것도 없다는 것을 확인할 것 (당신은 당신이지고있는 오류에서 것을 추측 할 수있다). 구문 분석 또는 다운로드가 실패 별도의 파일에 응답 저장을, 그 방법은 더 나은 문제를 진단 할 수 있습니다.
나는 또한 당신이 마지막으로 실패한 위치에서 프로세스를 다시 시작할 수 있도록, 다시 시작 메커니즘을 구현하는 대신에 모든 시간을 시작하는 시작에 약간의 시간을 투자한다. 또한 제 N 요청을 이동 입력으로 스킵 카운터를 제공하는 단순하게 할 수있다.
당신은 다시 사용해야하는 DocumentBuilderFactory
이 같은 DTD 때마다로드되지 않도록. 또한 (만 유효한 문서를 원하지 않는다면,이 경우에서의 캐치 좋은 그 예외는 검토를 위해 별도의 파일에 잘못된 XML 덤프)는 모두 해제 DTD 검증 할 수 있습니다.
private static DocumentBuilderFactory dbf;
public static void main(String[] args) {
dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
dbf.setFeature("http://xml.org/sax/features/validation", false);
...
}
private static Document parseXML(URL url) throws ParserConfigurationException, SAXException, IOException {
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse((url).openStream());
doc.getDocumentElement().normalize();
return doc;
}