I'm executing an ANT task using Java code, via an executable jar. I'd like to include the build.xml within the executable JAR, but can't figure out how to reference it in my code. Any help is appreciated.
public static void main(String[] args) {
BuildLogger logger = new DefaultLogger();
logger.setMessageOutputLevel(Project.MSG_INFO);
logger.setOutputPrintStream(System.out);
logger.setErrorPrintStream(System.out);
logger.setEmacsMode(true);
ProjectHelper ph = ProjectHelper.getProjectHelper();
Project p = new Project();
p.addBuildListener(logger);
p.init();
p.addReference("ant.projectHelper", ph);
//File f = new File(this.getClass().getResource("/report.xml").toURI()); I can't do toURI on this, it throws an exception
ph.parse(p, this.getClass().getResource("/report.xml")); //This throws a NullPointerException within ANT
p.executeTarget("dumpandreport");
}
If I create a java.io.File object that references an external build.xml file and specify that in ph.parse, this works...If I try to reference a file that is packaged within the JAR, this doesn't. I have validated (via 7-ZIP) that the file report.xml is, in fact, in the root of the JAR.
Well, disappointingly, I never did quite figure this out. You can, however, do the following:
public static void main(String[] args) {
...
ph.parse(p, getAntXML()};
...
}
private Object getAntXML() throws IOException {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
inputStream = this.getClass().getResourceAsStream("/report.xml");
File f = File.createTempFile("report", "xml");
outputStream = new FileOutputStream(f);
int read;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
return f;
} catch (IOException ex) {
throw ex;
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
//Nop
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
//Nop
}
}
}
}
This works well enough for my purposes anyway.
Related
How can I add a executable into assets and run it in Android and show the output?
I've a executable that will work. I assume there will need to be some chmod in the code.
Thank you.
here is my answer
put copyAssets() to your mainactivity.
someone's code:
private void copyAssets() {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
for(String filename : files) {
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filename);
File outFile = new File(getFilesDir(), filename);
out = new FileOutputStream(outFile);
copyFile(in, out);
} catch(IOException e) {
Log.e("tag", "Failed to copy asset file: " + filename, e);
}
finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// NOOP
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
// NOOP
}
}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
}
also here is code to run command
public String runcmd(String cmd){
try {
Process p = Runtime.getRuntime().exec(cmd);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer out = new StringBuffer();
while ((read = in.read(buffer)) > 0) {
out.append(buffer, 0, read);
}
in.close();
p.waitFor();
return out.substring(0);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
you may need to change it to
String prog= "programname";
String[] env= { "parameter 1","p2"};
File dir= new File(getFilesDir().getAbsolutePath());
Process p = Runtime.getRuntime().exec(prog,env,dir);
to ensure proper parameter handling
also add this to your main code
to check proper copying of files
String s;
File file4 = new File(getFilesDir().getAbsolutePath()+"/executable");
file4.setExecutable(true);
s+=file4.getName();
s+=file4.exists();
s+=file4.canExecute();
s+=file4.length();
//output s however you want it
should write: filename, true, true, correct filelength.
Place your executable in raw folder, then run it by using ProcessBuilder or Runtime.exec like they do here http://gimite.net/en/index.php?Run%20native%20executable%20in%20Android%20App
Today, I read the Basic I/O in the Java tutorial and I find some problem:
public class CopyCharacters {
public static void main(String[] args) throws IOException {
FileReader inputStream = null;
FileWriter outputStream = null;
try {
inputStream = new FileReader("/workspaces/test/a.txt");
outputStream = new FileWriter("/workspaces/test/b.txt");
int c;
while ((c = inputStream.read()) != -1) {
outputStream.write(c);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
}
But when I run the demo, it failed. In the Console:
Exception in thread "main" java.io.FileNotFoundException: /workspaces/test/b.txt (Access is denied)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
at java.io.FileOutputStream.<init>(FileOutputStream.java:110)
at java.io.FileWriter.<init>(FileWriter.java:63)
at Demo.CopyCharacters.main(CopyCharacters.java:13)
How can I do that?
File might have a lock and forbid you to open it for writing (i.e. your application is still on a break point in debug mode and you forgot to stop it or you killed the app and the process is still running in memory). You can check by doing this:
inputStream = new FileReader("/workspaces/test/a.txt");
File outFile = new File("/workspaces/test/b.txt");
if (!outFile.canWrite()) {
System.err.println("Cannot write into file: " + outFile.getAbsolutePath());
}
outputStream = new FileWriter(outFile);
You can also renname your out file "b.txt" for something else and it will work as before (until you locked it again by accident). An other way to do this is to use a temporary file:
public static void main(String[] args) throws Exception {
FileReader inputStream = null;
FileWriter outputStream = null;
try {
inputStream = new FileReader("/workspaces/test/a.txt");
File file = File.createTempFile("test", null);
outputStream = new FileWriter(file);
System.out.println(file.getAbsolutePath());
int c;
while ((c = inputStream.read()) != -1) {
outputStream.write(c);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
Good for coding (and debugging). It ensures that it will be deleted by the OS after.
Maybe you should try to use a new feature that takes care of your resources automatically by putting them inside the try-catch block?
public static void main(String[] args) throws IOException {
try (
FileReader inputStream = new FileReader("/workspaces/test/a.txt");
FileWriter outputStream = new FileWriter("/workspaces/test/b.txt");
)
{
int c;
while ((c = inputStream.read()) != -1) {
outputStream.write(c);
}
}
}
If you write your code in this manner, you don't need the finally block, because java will take care of the resources that are inside the try block brackets.
I want to write simple rest api for file download.
I cant find docs about it as I understood I need to set mimetype='application/zip' for response, but not clear how to return stream.
http://sparkjava.com/
update:
resolved here example code:
public static void main(String[] args) {
//setPort(8080);
get("/hello", (request, responce) -> getFile(request,responce));
}
private static Object getFile(Request request, Response responce) {
File file = new File("MYFILE");
responce.raw().setContentType("application/octet-stream");
responce.raw().setHeader("Content-Disposition","attachment; filename="+file.getName()+".zip");
try {
try(ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(responce.raw().getOutputStream()));
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file)))
{
ZipEntry zipEntry = new ZipEntry(file.getName());
zipOutputStream.putNextEntry(zipEntry);
byte[] buffer = new byte[1024];
int len;
while ((len = bufferedInputStream.read(buffer)) > 0) {
zipOutputStream.write(buffer,0,len);
}
}
} catch (Exception e) {
halt(405,"server error");
}
return null;
What you need is similar to this thread. You only need to close the OutputStream and return the raw HTTPServletResponse:
try {
...
zipOutputStream.flush();
zipOutputStream.close();
} catch (Exception e) {
halt(405,"server error");
}
return responce.raw();
Have a file on specified path /foo/file-a.txt and that file contains a path of another file
file-a.txt contains: /bar/file-b.txt this path at line one. need to parse the path of file-b.txt and zip that file and move that zipped file to another path /too/ from my Java code.
I been till the below code then i m stuck.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Reader
{
public static void main(String[] args)
{
BufferedReader br = null;
try
{
String CurrentLine;
br = new BufferedReader(new FileReader("/foo/file-a.txt"));
while ((CurrentLine = br.readLine()) != null)
{
System.out.println(CurrentLine);
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (br != null)br.close();
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
}
}
am getting path as text, help would be appreciated. Thanks in advance
For the actual zipping of the file, this page may be of help.
As a general note, this code will replace the current existing zip file.
public class TestZip02 {
public static void main(String[] args) {
try {
zip(new File("TextFiles.zip"), new File("sample.txt"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static void zip(File zip, File file) throws IOException {
ZipOutputStream zos = null;
try {
String name = file.getName();
zos = new ZipOutputStream(new FileOutputStream(zip));
ZipEntry entry = new ZipEntry(name);
zos.putNextEntry(entry);
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
byte[] byteBuffer = new byte[1024];
int bytesRead = -1;
while ((bytesRead = fis.read(byteBuffer)) != -1) {
zos.write(byteBuffer, 0, bytesRead);
}
zos.flush();
} finally {
try {
fis.close();
} catch (Exception e) {
}
}
zos.closeEntry();
zos.flush();
} finally {
try {
zos.close();
} catch (Exception e) {
}
}
}
}
For moving the file, you can use File.renameTo, here's an example.
Hope this helps!
There's something going on here that I don't understand. This code deletes all the files in the "stuff"directory:
public static void main(String[] args) throws Exception {
File dire = new File("C:\\Users\\spacitron\\Desktop\\Stuff");
for (File doc : dire.listFiles()) {
doc.delete();
}
}
However it won't work if I try to do something useful with it, such as only deleting duplicate files:
public static void main(String[] args) throws Exception {
File dire = new File("C:\\Users\\spacitron\\Desktop\\Stuff");
ArrayList<String> hashes = new ArrayList<>();
for (File doc : dire.listFiles()) {
String docHash = getHash(doc);
if (hashes.contains(docHash)) {
doc.delete();
} else {
hashes.add(docHash);
}
}
}
public static String getHash(File d) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA1");
FileInputStream inStream = new FileInputStream(d);
DigestInputStream dis = new DigestInputStream(inStream, md);
BufferedInputStream bis = new BufferedInputStream(dis);
while (true) {
int b = bis.read();
if (b == -1)
break;
}
} catch (NoSuchAlgorithmException | IOException e) {
e.printStackTrace();
}
BigInteger bi = new BigInteger(md.digest());
return bi.toString(16);
}
What gives?
You need to close your input streams in a finally block would be best, These will be accessing you files still preventing them from being deleted as they are in use
FileInputStream inStream = null;
DigestInputStream dis = null;
BufferedInputStream bis = null;
try {
md = MessageDigest.getInstance("SHA1");
inStream = new FileInputStream(d);
dis = new DigestInputStream(inStream, md);
bis = new BufferedInputStream(dis);
while (true) {
int b = bis.read();
if (b == -1)
break;
}
} catch (NoSuchAlgorithmException | IOException e) {
e.printStackTrace();
} finally {
try{
if(inStream!= null)
inStream.close();
if(dis != null)
dis.close();
if(bis != null)
bis.close()
} catch (Exception ex){
ex.printStackTrace()
}
}
Windows does not permit deleting files that are open, unless they are opened with a special flag that is unavailable when programming in Java. While this code would work on a Unix system, on Windows it won't.
Closing open files is a good idea in general because operating systems impose a limit on the number of files that an application can have open at any given time.