Dynamic Exe Parameters on Java - java

I'm trying to make a loop that pass through a folder for files, then the script only takes the files with the extension .wav, so I call an exe with two parameters and converts the audio. Without a loop works, because the command is a String[] variable and I just have to put my parameters in parentheses, but when I tried to make it all dynamic nothing happens, even I tried the normal static version, but the parameters in two separated strings, then I've added those strings to the String[] that contains the command to execute the application and it just doesnt' work. This is the code (With loop):
File dir = new File("moved");
File[] dirlist = dir.listFiles();
for(File f3 : dirlist)
{
if(f3.getName().endsWith(".wav"))
{
String firstnam = f3.getName();
String secondnam = firstnam.replaceFirst(".wav", "_converted.wav")
String[] command = {"cmd", "/c", "AdpcmEncode.exe", firstnam, secondnam};
Runtime rt = Runtime.getRuntime();
Process process = rt.exec(command, null, dir);
}
}
What I need most is to know how to pass these dynamic parameters into the command, if it's posible also know how to change names through audio conversions (the input and output can't be the same).

Well after a research about this, I have finally put my code in a separate class from the main JFrame (That fixed the dynamic parameters, for some reason I don't understand, I have to say that code I had it into another JFrame Class), now because the code is into an IOException, the thing was a little bit complicated, but I realize that it was simple like this:
try{
ConvertAllClass.converter(null);
}catch(IOException e){
//e.printStackTrace();
}
Maybe the null is not necessary, but all works. This is the "test" function (I just wanted to know if converts one audio at least):
public class ConvertAllClass {
public static void converter(String args[]) throws IOException {
File f = new File("C:\\convertion_kit\\bin");
String firstnam = "mx_game_over.wav";
String secondnam = "mx_done.wav";
ProcessBuilder pb = new ProcessBuilder("cmd", "/c","start","AdpcmEncode.exe", firstnam, secondnam );
pb.directory(f);
Process process = pb.start();
}
}

Related

ImageMagick's Convert for EPS to JPEG not being called properly

M primary goal is to take in a series of .eps files and convert them to .jpg using ImageMagick and GhostScript. I have both ImageMagick and GhostScript installed in a Windows environment. I am referencing ImageMagick's convert command using Process in java with no luck. Using Window's cmd tool, I successfully converted an EPS to JPEG by navigating to C:\Program Files\ImageMagick-6.8.9-Q16 and using the following command:
convert Raw\R_GiftcardSizeNew3x5.eps Converted\R_GiftcardSizeNew3x5.jpg
In Java, I use almost the exact same command in the following code:
public void convertEPStoJPG()
{ //commands
ArrayList<String> cmds = new ArrayList<String>();
//absolute file paths of eps files retrieved using a helper method
ArrayList<String> filePaths = this.getFilePaths();
//beginning cmd line calls
cmds.add("cmd.exe");
cmds.add("/c");
cmds.add("cd C:\\Program Files\\ImageMagick-6.8.9-Q16\\");
for (int i = 0; i < filePaths.size(); i++)
{
//conversion calls
String tempPath = filePaths.get(i);
//shortening path name
tempPath = tempPath.substring(tempPath.lastIndexOf("\\") + 1, tempPath.length());
//adding command of "convert Raw\\image.eps Converted\\image.jpg"
cmds.add("convert \\Naked Wines\\Raw\\" + tempPath + " \\Naked Wines\\Converted\\" +
tempPath.substring(0,tempPath.length() - 3) + "jpg");
}
//building process with commands
ProcessBuilder pb = new ProcessBuilder(cmds);
Process process;
try {
pb.redirectErrorStream(true);
//executing commands
process = pb.start();
BufferedReader r = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while (true) {
line = r.readLine();
if (line == null) { break; }
//print output from command execution
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
where my files im trying to grab are C:\Program Files\ImageMagick-6.8.9-Q16\Naked Wines\Raw
and the destination I am converting to is C:\Program Files\ImageMagick-6.8.9-Q16\Naked Wines\Converted.
I get an error stating "The system cannot find the path specified". Looking at previously answered questions such as How to override Windows' convert command by ImageMagick's one?, people suggest you have to override Windows convert command. Would this be the cause of error, or is there something I am missing? I'm fairly new to ImageMagick and might have missed or misunderstood something.
I ended up approaching this problem in a different way using Im4Java, a pure-java interface to the ImageMagick commandline. I installed the libraries via http://im4java.sourceforge.net/#download. Here is my code for converting eps to jpg:
public void convertESPtoJPG()
{
//initialize ImageMagick operation
IMOperation op = new IMOperation();
//setting my path allows us to use ImageMagicks "convert" vs. Windows "convert"
String myPath="C:\\Program Files\\ImageMagick-6.8.9-Q16";
ProcessStarter.setGlobalSearchPath(myPath);
op.addImage(); //in
op.addImage(); //out
ConvertCmd cmd = new ConvertCmd();
//filter out files for eps files, and load the files using included FilenameLoader
ExtensionFilter filter = new ExtensionFilter("eps");
FilenameLoader loader = new FilenameLoader(filter);
List<String> files = loader.loadFilenames("C:\\Program Files\\ImageMagick-6.8.9-
Q16\\NakedWines\\Raw\\");
//what we plan on converting our eps files to
FilenamePatternResolver resolver = new FilenamePatternResolver("%P/%f.jpg");
//iterate through loaded files
for (String img: files)
{
try {
//execute our convert commands
cmd.run(op,img,resolver.createName(img));
} catch (Exception e) {
e.printStackTrace();
}
}
}
I found this method to be much easier to understand and more forward as well.

What is the simplest way to create a file?

This doesn't seem to create a file or folder. Why?
import java.io.*;
public class file1
{
public static void main(String[] args)
{
File text1 = new File("C:/text1.txt");
File dir1 = new File("C:/dir");
}
This one below does create a file.
import java.io.*;
public class file3
{
public static void main(String[] args)
{
try
{
FileWriter text1 = new FileWriter("C:/text.txt");
FileWriter dir = new FileWriter("C:/dir");
}
catch(Exception e){}
}
}
However, the directory seems to have a strange unusable icon.
What can I do to create a directory.
What are other simple methods to create files and folders.
Surprisingly, the File class does not represent a file. It actually represents a pathname for a file ... that may or may not exist.
To create a file in Java, you need to open it for output; e.g.
File text1 = new File("C:/text1.txt");
FileOutputStream os = new FileOutputStream(text1); // The file is created
// here ... if it doesn't
// exist already.
// then write to the file and close it.
or you could do this - new FileOutputStream("C:/text1.txt"). In both cases, an existing file will be truncated ... unless you use the FileOutputStream with a boolean parameter that says open for appending.
If you want to create a file without writing any data to it, you could also do this:
File text1 = new File("C:/text1.txt");
text1.createNewFile();
However, that will only create a new file if the file didn't already exist.
To create a directory in Java, use the File.mkdir() or File.mkdirs() methods.
UPDATE
You commented:
I tried File dir = new File("C:/dir1").mkdir(); it says incompatible types.
That is right. The mkdir() method returns a boolean to say whether or not it created the directory. What you need to write is something like this:
File dir = new File("C:/dir1");
if (dir.mkdir()) {
System.out.println("I created it");
}
Always READ THE JAVADOCS before using a method or class you are not familiar with!
A couple more things you need to know:
The best way to deal with the problem of making sure a file gets closed is to do something like this:
try (FileOutputStream os = new FileOutputStream(text1)) {
// now write to it
}
The stream os will be closed automatically when the block exits.
It is usually "bad practice" to catch Exception. It is always "bad practice" to catch Exception and do nothing in the handler. This kind of this hides the evidence of bugs, and makes your code unpredictable and hard to debug.
If you're creating a directory with File, you want this:
new File("C:/dir").mkdirs();
For creating directory you can use :
if(!text1.exists()){
text1.mkdir();
}
and for creating file use:
if(!text1.exists()){
try {
text1.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}

Text input and output java

I am trying to read 2 files after i read the files i want to get their contents and manipulate the contents of the two files then update a new file which is the output. The files are in the same folder as the program but the program always throws a FileNotFoundException.
Below is my code:-
import java.io.*;
import java.util.Scanner;
public class UpdateMaster {
public static void main(String[] args)
{
String master = "Customer.dat";
String trans = "Transactns.dat";
String newMaster = "Temp.txt";
Scanner inputStreamMaster = null;
Scanner inputStreamTrans = null;
PrintWriter inputStreamNewMaster = null;
try
{
inputStreamMaster = new Scanner(new File(master));
inputStreamTrans = new Scanner(new File(trans));
inputStreamNewMaster = new PrintWriter(newMaster);
}
catch(FileNotFoundException e)
{
System.out.println("Error: you opend a file that does not exist.");
System.exit(0);
}
catch(IOException e)
{
System.out.println("Error.");
System.exit(0);
}
do
{
String transLine = inputStreamTrans.nextLine();
String masterLine = inputStreamMaster.nextLine();
String[] transLineArr = transLine.split(",");
String[] masterLineArr = masterLine.split(",");
int trAccNo = Integer.parseInt(transLineArr[0]);
int sales = Integer.parseInt(transLineArr[1]);
int masterAccNo = Integer.parseInt(masterLineArr[0]);
int balance = Integer.parseInt(masterLineArr[1]);
while(masterAccNo== trAccNo){
inputStreamNewMaster.println(trAccNo+ " , "+masterAccNo);
masterLine = inputStreamMaster.nextLine();
masterLineArr = masterLine.split(",");
masterAccNo = Integer.parseInt(masterLineArr[0]);
balance = Integer.parseInt(masterLineArr[1]);
}
balance = balance + sales;
inputStreamNewMaster.println(masterAccNo+ " , "+balance);
}while(inputStreamTrans.hasNextLine());
inputStreamMaster.close();
inputStreamTrans.close();
inputStreamNewMaster.close();
//System.out.println(" the line were written to "+ newMaster);
}
}
Like #Ankit Rustagi said in the comments, you need the full path of the files if you want to keep the current implementation.
However, there is a solution where you only need the file names: use BufferedReader / BufferedWriter. See here an example on how to use these classes (in the example it uses the full path but it works without it too).
Use absolute path
String master = "C:/Data/Customer.dat";
String trans = "C:/Data/Transactns.dat";
String newMaster = "C:/Data/Temp.txt";
The code works for me, i guess you misspelled some filename(s) or your files are in the wrong folder. I created your files on the same level as the src or the project. Also this is the folder where the files are exspected.
There's nothing wrong with using relative paths like tihis. What's happening is that your program is looking for the files in the directory where you execute the program, which doesn't have to be the folder of the program. You can confirm this by logging the absolute path of the files before you try to read them. For example:
File masterFile = new File(master);
System.out.printf("Using master file '%s'%n", masterFile.getAbsolutePath());
inputStreamMaster = new Scanner(masterFile);
In general you should not hardcode file paths but allow the user to specify them in someway, for example using command line arguments, a configuration file with a well known path, or an interactive user interface.
There is a way to locate the program's class file but it's a little tricky because Java allows classes to be loaded from compressed archives that may be located in remote systems. It's better to solve this problem in some other manner.
Try this:
String current = new java.io.File( "." ).getCanonicalPath();
System.out.println("I look for files in:"+current);
To see what directory your program expects to find its input files. If it shows the correct directory, check spelling of filenames. Otherwise, you have a clue as to what's gone wrong.

Empty output file is generated when Java Process is run

I'm having some problems with a certain segment of my code. What is supposed to happen is that the Java program takes some predetermined variables and uses UNIX's "sed" function to replace the Strings "AAA" and "BBB" in a pre-written shell script. I have three methods to do this: one that replaces the Strings in the file using "sed" and writes the output to a different file; one that removes the original file with the "rm" command; and one that renames the output file to the name of the original file using "mv". There are three copies of the shell script in three different directories, and each one should be replaced with it's own specific variables.
The replacement should occur for all three shell script files, but it only occurs for two. On the third shell script, it seems as if the process did not complete, because the byte size of that file is 0. The file that is not replaced is completely random, so it's not the same file not working during each run.
I'm not sure why this error is occuring. Does anyone have any possible solutions? Here is the code:
public void modifyShellScript(String firstParam, String secondParam, int thirdParam, int fourthParam, String outfileDirectoryPath) throws IOException{
String thirdDammifParamString = "";
String fourthDammifParamString = "";
thirdDammifParamString = Integer.toString(thirdDammifParam);
fourthDammifParamString = Integer.toString(fourthDammifParam);
String[] cmdArray3 = {"/bin/tcsh","-c", "sed -e 's/AAA/"+firstDammifParam+"/' -e 's/BBB/"+secondDammifParam+"/' -e 's/C/"+thirdDammifParamString+"/' -e 's/D/"+fourthDammifParam+"/' "+outfileDirectoryPath+"runDammifScript.sh > "+outfileDirectoryPath+"runDammifScript.sh2"};
Process p;
p = Runtime.getRuntime().exec(cmdArray3);
}
public void removeOriginalShellScript(String outfileDirectoryPath) throws IOException{
String[] removeCmdArray = {"/bin/tcsh", "-c", "rm "+outfileDirectoryPath+"runDammifScript.sh"};
Process p1;
p1 = Runtime.getRuntime().exec(removeCmdArray);
}
public void reconvertOutputScript(String outfileDirectoryPath) throws IOException{
String[] reconvertCmdArray = {"/bin/tcsh","-c","mv "+outfileDirectoryPath+"runDammifScript.sh2 "+outfileDirectoryPath+"runDammifScript.sh"};
Process reconvert;
reconvert = Runtime.getRuntime().exec(reconvertCmdArray);
}
If you haven't already, take a look at When Runtime.exec() won't. One or more Process might be hanging because you aren't consuming the output and error streams. In particular, look at the StreamGobbler in that article's examples.
It could also be the case that you're forgetting to include a trailing slash in outfileDirectoryPath. Read the Process' error stream to see what's going wrong:
InputStream err = p.getErrorStream();
// read the stream and print its contents to the console, or whatever
Keep in mind that you'll want to read the streams in separate threads.
That said, I would personally just do all of this natively in Java instead of relying on external, platform-specific dependencies.
For substring replacement, read the file to a String, then use String.replace and/or String.replaceAll.
You can replace removeOriginalShellScript's body with a call to File.delete:
public void removeOriginalShellScript(String outfileDirectoryPath) throws IOException{
File f = new File(outfileDirectoryPath, "runDammifScript.sh");
f.delete();
}
You can replace reconvertOutputScript's body with a call to Files.move:
public void reconvertOutputScript(String outfileDirectoryPath) throws IOException{
File src = new File(outfileDirectoryPath, "runDammifScript.sh2");
File dst = new File(outfileDirectoryPath, "runDammifScript.sh");
Files.move(src, dst);
}
Or just replace both removeOriginalShellScript and reconvertOoutputScript with a call to Files.move, specifying the REPLACE_EXISTING option:
File src = new File(outfileDirectoryPath, "runDammifScript.sh2");
File dst = new File(outfileDirectoryPath, "runDammifScript.sh");
Files.move(src, dst, REPLACE_EXISTING);

Executing JAR file within another java application

I'm trying to run a External Jar file, without actually inserting it into my jar itself. Because the jar file needs to be located in the same folder as the main jar file.
So, Within the main jar file I want to execute the other executable jar file, And I need to be able to know when the jar file is ended AND when you close the main jar file, the jar file that is started within the jar file needs to be closed to,
I currently do that by using this code:
public void LaunchLatestBuild()
{
try {
String path = new File(".").getCanonicalPath() +
"\\externaljar.jar";
List commands = new ArrayList();
commands.add(getJreExecutable().toString());
commands.add("-Xmx" + this.btd_serverram + "M");
commands.add("-Xms" + this.btd_serverram + "M");
commands.add("-jar");
commands.add(path);
int returnint = launch(commands); //It just waits and stops the tread here. And my Runtime.getRuntime().addShutdownHook doesn't get triggerd.
if (returnint != 201) //201 is a custom exit code I 'use' to know when the app needs a restart or not.
{
System.out.println("No restart needed! Closing...");
System.exit(1);
}
else
{
CloseCraftBukkit();
Launcher.main(new String[] { "" });
}
}
catch (Exception e)
{
System.out.println(e.toString());
e.printStackTrace();
}
}
public int launch(List<String> cmdarray) throws IOException, InterruptedException
{
byte[] buffer = new byte[1024];
ProcessBuilder processBuilder = new ProcessBuilder(cmdarray);
processBuilder.redirectErrorStream(true);
this.CBProcess = processBuilder.start();
InputStream in = this.CBProcess.getInputStream();
while (true) {
int r = in.read(buffer);
if (r <= 0) {
break;
}
System.out.write(buffer, 0, r);
}
return this.CBProcess.exitValue();
}
Limitations of this code:
Doesn't close my externaljar.jar java
process on exit of the main
application.
Cannot redirect input if main console, to external jar.
That are the most Important things I need.
I hope someone can tell me how I should do this.
Current source code is available at:
http://code.google.com/p/bukkit-to-date/
Why can't you just set your classpath so that it includes the second jar, and then you can simply use it as a library ? You can even invoke the MainClass.main() method manually, if you really want that to be executed, but from within the same VM and without spawning a separate process.
EDIT: If you don't know the name of the jar file when your application is launched, but you'll only figure that out at runtime, in order to invoke it, create a URLClassLoader provided with the path to your jar file and then:
URLClassLoader urlClassLoader = new URLClassLoader(
new File("/path/to/your/jar/file.jar").toURI().toURL() );
ClassLoader cl = Thread.currentThread().getContextClassLoader();
// switch to your custom CL
Thread.currentThread().setContextClassLoader(urlClassLoader);
// do your stuff with the other jar
// ....................
// now switch back to the original CL
Thread.currentThread().setContextClassLoader(cl);
Or simply grab a reference to a class in that other jar and make use of reflection:
Class<?> c = urlClassLoader.loadClass("org.ogher.packag.ClassFromExternalJar");

Categories

Resources