我在Java线程中遇到“串扰”问题。如果我启动多线程进程(如jsoup或wget downloads),那些写入这些命令输出的文本文件有时会有控制台输出而不是所需的CSV数据。
我该如何避免这种情况?
以下是一些执行此操作的代码 - 完整代码,因此没有“什么是X?问题”:
“ShellUtils.java”
package jASUtils;
import java.io.*;
import java.nio.charset.*;
import java.nio.file.*;
import java.util.List;
import java.util.Scanner;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.jsoup.*;
public class ShellUtils {
public static String fileScanner(String path, Charset encoding) throws IOException {
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
public static void jsoupOutFile(String thisUrl, File outFile) {
System.out.println(" --> Downloading [ "+thisUrl+" ] NO MIME");
PrintStream console = System.out;
try {
org.jsoup.Connection.Response html = Jsoup.connect(thisUrl).ignoreContentType(true).execute();
System.setOut(new PrintStream(new FileOutputStream(outFile, false)));
System.out.println(html.body());
}
catch (Exception e) { e.printStackTrace(); }
System.out.flush();
System.setOut(console);
}
public static void deleteDir(File file) {
File[] contents = file.listFiles();
if (contents != null) {
for (File f : contents) { deleteDir(f); }
}
file.delete();
}
public static void moveFile(String oldFileName, String newFileName) {
System.out.println(" --> Moving [ "+oldFileName+" ] to [ "+newFileName+" ]");
Path oldFileFile = Paths.get(oldFileName);
Path newFileFile = Paths.get(newFileName);
new File(newFileName).delete();
try { Files.move(oldFileFile, newFileFile); } catch (IOException io) { io.printStackTrace(); }
}
public static void runProcess(String pString) {
System.out.println(" --> Running [ "+pString+" ]");
String s = null;
String[] pArray = { "bash", "-c", pString };
try {
Process p = new ProcessBuilder(pArray).start();
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
while ((s = stdInput.readLine()) != null) { System.out.println(s); }
while ((s = stdError.readLine()) != null) { System.out.println(s); }
}
catch (IOException e) { e.printStackTrace(); }
}
public static void runProcessOutFile(String pString, File outFile, boolean appendFlag) throws FileNotFoundException {
PrintStream console = System.out;
try { System.setOut(new PrintStream(new FileOutputStream(outFile, appendFlag))); runProcess(pString); }
catch (Exception e) { e.printStackTrace(); }
System.out.flush();
System.setOut(console);
}
public static String runProcessOutVar(String pString) {
PrintStream console = System.out;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream thisStream = new PrintStream(baos);
System.setOut(thisStream);
try { runProcess(pString); }
catch (Exception e) { e.printStackTrace(); }
String thisOutputString = baos.toString();
System.out.flush();
System.setOut(console);
return thisOutputString;
}
public static void sedFileDeleteFirstLine(String fileName) {
try {
File thisFileObject = new File(fileName);
Scanner fileScanner = new Scanner(thisFileObject);
fileScanner.nextLine();
FileWriter fileStream = new FileWriter(thisFileObject);
BufferedWriter out = new BufferedWriter(fileStream);
while (fileScanner.hasNextLine()) {
String next = fileScanner.nextLine();
if(next.equals("\n")) { out.newLine(); } else { out.write(next); }
out.newLine();
}
out.close();
} catch (IOException ix) { ix.printStackTrace(); }
}
public static void sedFileInsertEachLineNew(String subjectFile, String toInsert, String targetFile) {
try {
FileInputStream fstream = new FileInputStream(subjectFile);
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
BufferedWriter bw = new BufferedWriter(new FileWriter(new File(targetFile), true));
String strLine = null;
while ((strLine = br.readLine()) != null) {
String upLine = toInsert+strLine;
bw.write(upLine);
bw.newLine();
}
bw.close();
br.close();
}
catch (FileNotFoundException fnf) { fnf.printStackTrace(); }
catch (IOException iox) { iox.printStackTrace(); }
}
public static void sedFileReplace(String fileName, String toFind, String replaceTo) {
Path path = Paths.get(fileName);
Charset charset = StandardCharsets.UTF_8;
try {
String content = new String(Files.readAllBytes(path), charset);
content = content.trim().replaceAll(toFind, replaceTo);
Files.write(path, content.getBytes(charset));
}
catch (IOException io) { io.printStackTrace(); }
}
public static void unTarGz(String tarFileStr, String destStr) {
File tarFile = new File(tarFileStr);
File dest = new File(destStr);
dest.mkdirs();
TarArchiveInputStream tarIn = null;
try {
tarIn = new TarArchiveInputStream(new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(tarFile))));
TarArchiveEntry tarEntry = tarIn.getNextTarEntry();
while (tarEntry != null) {
File destPath = new File(dest, tarEntry.getName());
System.out.println("Working: " + destPath.getCanonicalPath());
if (tarEntry.isDirectory()) { destPath.mkdirs(); }
else {
if(!destPath.getParentFile().exists()) { destPath.getParentFile().mkdirs(); }
destPath.createNewFile();
byte [] btoRead = new byte[4096];
BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(destPath));
int len = 0;
while ((len = tarIn.read(btoRead)) != -1) { bout.write(btoRead, 0, len); }
bout.close();
btoRead = null;
}
tarEntry = tarIn.getNextTarEntry();
}
tarIn.close();
}
catch (FileNotFoundException fnf) { fnf.printStackTrace(); }
catch (IOException iox) { iox.printStackTrace(); }
}
public static void unzipFile(String zipFile, String outputFolder) {
byte[] buffer = new byte[4096];
try {
File folder = new File(outputFolder);
if(!folder.exists()) { folder.mkdirs(); }
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(zipFile)));
ZipEntry ze = zis.getNextEntry();
while(ze != null) {
String fileName = ze.getName();
File newFile = new File(outputFolder+File.separator+fileName);
System.out.println("Unzip : "+newFile.getAbsoluteFile());
new File(newFile.getParent()).mkdirs();
FileOutputStream fos = new FileOutputStream(newFile);
int len;
while ((len = zis.read(buffer)) > 0) { fos.write(buffer, 0, len); }
fos.close();
ze = zis.getNextEntry();
}
zis.closeEntry();
zis.close();
System.out.println("Done");
} catch (IOException ex) { ex.printStackTrace(); }
}
}
“GetSPC.java”
package jASUtils;
import java.io.*;
import java.sql.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Scanner;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import jASUtils.ShellUtils;
public class GetSPC {
public static void main(String args[]) {
final PrintStream console = System.out;
System.setOut(console);
Date nowDate = new Date();
DateFormat nowDateFormat = new SimpleDateFormat("yyMMdd");
DateFormat sqlDateFormat = new SimpleDateFormat("yyyy-MM-dd");
DateFormat yearFormat = new SimpleDateFormat("yyyy");
String spcDate = nowDateFormat.format(nowDate);
String spcSQLDate = sqlDateFormat.format(nowDate);
String spcYear = yearFormat.format(nowDate);
final DateTime dtdspcdy = new DateTime().minusDays(1);
final DateTimeFormatter dtfspcdy = DateTimeFormat.forPattern("yyMMdd");
final DateTimeFormatter dtfspcsqldy = DateTimeFormat.forPattern("yyyy-MM-dd");
String spcDateY = dtfspcdy.print(dtdspcdy);
String spcSQLDateY = dtfspcsqldy.print(dtdspcdy);
final String spcBaseURL = "http://www.spc.noaa.gov/climo/reports/";
final String mysqlShare = "/var/lib/mysql-files";
final String tmpPathStr = "/dev/shm/fetchSPCj";
final File tmpPath = new File(tmpPathStr);
tmpPath.mkdirs();
File spcReportsTFile = new File(tmpPath+"/SPCReportsT.csv");
File spcReportsHFile = new File(tmpPath+"/SPCReportsH.csv");
File spcReportsWFile = new File(tmpPath+"/SPCReportsW.csv");
File spcReportsYTFile = new File(tmpPath+"/SPCReportsYT.csv");
File spcReportsYHFile = new File(tmpPath+"/SPCReportsYH.csv");
File spcReportsYWFile = new File(tmpPath+"/SPCReportsYW.csv");
File spcWWkmzFile = new File(tmpPath+"/ActiveWW.kmz");
File spcMDkmzFile = new File(tmpPath+"/ActiveMD.kmz");
Thread thA1 = new Thread(new Runnable() { public void run() { ShellUtils.jsoupOutFile(spcBaseURL+spcDate+"_rpts_filtered_torn.csv", spcReportsTFile); }});
Thread thA2 = new Thread(new Runnable() { public void run() { ShellUtils.jsoupOutFile(spcBaseURL+spcDate+"_rpts_filtered_hail.csv", spcReportsHFile); }});
Thread thA3 = new Thread(new Runnable() { public void run() { ShellUtils.jsoupOutFile(spcBaseURL+spcDate+"_rpts_filtered_wind.csv", spcReportsWFile); }});
Thread thA4 = new Thread(new Runnable() { public void run() { ShellUtils.jsoupOutFile(spcBaseURL+spcDateY+"_rpts_filtered_torn.csv", spcReportsYTFile); }});
Thread thA5 = new Thread(new Runnable() { public void run() { ShellUtils.jsoupOutFile(spcBaseURL+spcDateY+"_rpts_filtered_hail.csv", spcReportsYHFile); }});
Thread thA6 = new Thread(new Runnable() { public void run() { ShellUtils.jsoupOutFile(spcBaseURL+spcDateY+"_rpts_filtered_wind.csv", spcReportsYWFile); }});
Thread thA7 = new Thread(new Runnable() { public void run() { ShellUtils.runProcess("wget -O \""+spcWWkmzFile+"\" \"http://www.spc.noaa.gov/products/watch/ActiveWW.kmz\""); }});
Thread thA8 = new Thread(new Runnable() { public void run() { ShellUtils.runProcess("wget -O \""+spcMDkmzFile+"\" \"http://www.spc.noaa.gov/products/md/ActiveMD.kmz\""); }});
Thread thListA[] = { thA1, thA2, thA3, thA4, thA5, thA6, thA7, thA8 };
for (Thread thread : thListA) { thread.start(); }
for (int i = 0; i < thListA.length; i++) { try { thListA[i].join(); } catch (InterruptedException nx) { nx.printStackTrace(); } }
Thread thB1 = new Thread(new Runnable() { public void run() { ShellUtils.unzipFile(tmpPathStr+"/ActiveWW.kmz", tmpPathStr); }});
Thread thB2 = new Thread(new Runnable() { public void run() { ShellUtils.unzipFile(tmpPathStr+"/ActiveMD.kmz", tmpPathStr); }});
Thread thListB[] = { thB1, thB2 };
for (Thread thread : thListB) { thread.start(); }
for (int i = 0; i < thListB.length; i++) { try { thListB[i].join(); } catch (InterruptedException nx) { nx.printStackTrace(); } }
Thread thC1 = new Thread(new Runnable() { public void run() { ShellUtils.sedFileDeleteFirstLine(tmpPath+"/SPCReportsT.csv"); }});
Thread thC2 = new Thread(new Runnable() { public void run() { ShellUtils.sedFileDeleteFirstLine(tmpPath+"/SPCReportsH.csv"); }});
Thread thC3 = new Thread(new Runnable() { public void run() { ShellUtils.sedFileDeleteFirstLine(tmpPath+"/SPCReportsW.csv"); }});
Thread thC4 = new Thread(new Runnable() { public void run() { ShellUtils.sedFileDeleteFirstLine(tmpPath+"/SPCReportsYT.csv"); }});
Thread thC5 = new Thread(new Runnable() { public void run() { ShellUtils.sedFileDeleteFirstLine(tmpPath+"/SPCReportsYH.csv"); }});
Thread thC6 = new Thread(new Runnable() { public void run() { ShellUtils.sedFileDeleteFirstLine(tmpPath+"/SPCReportsYW.csv"); }});
Thread thListC[] = { thC1, thC2, thC3, thC4, thC5, thC6 };
for (Thread thread : thListC) { thread.start(); }
for (int i = 0; i < thListC.length; i++) { try { thListC[i].join(); } catch (InterruptedException nx) { nx.printStackTrace(); } }
File spcMDkmlFile = new File("/home/astump/src/codex/Java/jASUtils/testOut/GetSPC/ActiveMD.kml");
File spcWWkmlFile = new File(tmpPath+"/ActiveWW.kml");
ShellUtils.sedFileInsertEachLineNew(tmpPath+"/SPCReportsT.csv","T,"+spcSQLDate+",",tmpPath+"/SPCReportsLive.csv");
ShellUtils.sedFileInsertEachLineNew(tmpPath+"/SPCReportsH.csv","H,"+spcSQLDate+",",tmpPath+"/SPCReportsLive.csv");
ShellUtils.sedFileInsertEachLineNew(tmpPath+"/SPCReportsW.csv","W,"+spcSQLDate+",",tmpPath+"/SPCReportsLive.csv");
ShellUtils.sedFileInsertEachLineNew(tmpPath+"/SPCReportsYT.csv","T,"+spcSQLDate+",",tmpPath+"/SPCReportsLive.csv");
ShellUtils.sedFileInsertEachLineNew(tmpPath+"/SPCReportsYH.csv","H,"+spcSQLDateY+",",tmpPath+"/SPCReportsLive.csv");
ShellUtils.sedFileInsertEachLineNew(tmpPath+"/SPCReportsYW.csv","W,"+spcSQLDateY+",",tmpPath+"/SPCReportsLive.csv");
}
}