ProcessBuilder with gunzip does not work - java

I am trying to run this code which fails with the note:
gzip: /home/idob/workspace/DimesScheduler/*.gz: No such file or directory
The code:
ProcessBuilder gunzipPB = new ProcessBuilder("gunzip", System.getProperty("user.dir") + File.separator + "*");
gunzipPB.inheritIO();
int gunzipProcessExitValue;
try {
gunzipProcessExitValue = gunzipPB.start().waitFor();
} catch (InterruptedException | IOException e) {
throw new RuntimeException("Service " + this.getClass().getSimpleName() + " could not finish creating WHOIS AS Prefix Table", e);
}
logger.info("Finished unzipping radb and ripe files. Process exit value : {}", gunzipProcessExitValue);
Exit value is 1.
Same command in terminal works just fine (the files exist).
What can be the problem?
Thanks.
Ido
EDIT:
After trying to use DirectoryStrem I am getting this exception:
java.nio.file.NoSuchFileException: /home/idob/workspace/DimesScheduler/*.gz
Any idea what can be the problem? The files do exist.
The full code:
ProcessBuilder radbDownloadPB = new ProcessBuilder("wget", "-q", "ftp://ftp.radb.net /radb/dbase/*.db.gz");
ProcessBuilder ripeDownloadPB = new ProcessBuilder("wget", "-q", "ftp://ftp.ripe.net/ripe/dbase/split/ripe.db.route.gz");
radbDownloadPB.inheritIO();
ripeDownloadPB.inheritIO();
try {
int radbProcessExitValue = radbDownloadPB.start().waitFor();
logger.info("Finished downloading radb DB files. Process exit value : {}", radbProcessExitValue);
int ripeProcessExitValue = ripeDownloadPB.start().waitFor();
logger.info("Finished downloading ripe DB file. Process exit value : {}", ripeProcessExitValue);
// Unzipping the db files - need to process each file separately since java can't do the globing of '*'
try (DirectoryStream<Path> zippedFilesStream = Files.newDirectoryStream(Paths.get(System.getProperty("user.dir"), "*.gz"))){
for (Path zippedFilePath : zippedFilesStream) {
ProcessBuilder gunzipPB = new ProcessBuilder("gunzip", zippedFilePath.toString());
gunzipPB.inheritIO();
int gunzipProcessExitValue = gunzipPB.start().waitFor();
logger.debug("Finished unzipping file {}. Process exit value : {}", zippedFilePath, gunzipProcessExitValue);
}
}
logger.info("Finished unzipping ripe and radb DB file");
} catch (InterruptedException | IOException e) {
throw new RuntimeException("Service " + this.getClass().getSimpleName() + " could not finish creating WHOIS AS Prefix Table", e);
}
Thanks...

the *.gz glob is not handled by the gunzip command, but the shell. For example, the shell will translate gunzip *.gz to gunzip a.gz b.gz. Now when you exec through java, you either have to invoke bash to do the globbing for you, or expand the glob in java, since gzip doesn't know how to handle the glob.
Java 7 has new libraries which make expanding glob patterns easier.

Related

How to merge one file to another \ Linux

I am trying to append one text file to another by using linux commands from my Java program. I am completely new to Linux. I tried sorting and it works just fine, so I have no idea what I am doing wrong with using 'cat'.
Could you please review my code and help me figure out what I am doing wrong.
public static void mergeRecords(String fileName, String overflowFileName)
{
String command = "cat " + overflowFileName + " >> " + fileName;
try {
Process r = Runtime.getRuntime().exec(command);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Runtime#exec is not a shell.
This is a very common misconception. What you need to do is:
create a Process with the command cat file1 file2,
take the output of that process,
dump that output into a file.
Hint: use a ProcessBuilder, this will make your job much easier.
As others have pointed out, you should not use external commands to do something Java can easily do:
try (OutputStream existingFile = Files.newOutputStream(
Paths.get(fileName),
StandardOpenOption.WRITE,
StandardOpenOption.APPEND)) {
Files.copy(Paths.get(overflowFileName), existingFile);
}

Unable to delete files in system dir using Java

I am trying to delete a folder and its files in C:\Program Files\folder\files. I am not the creator of the folder but I do have admin rights in this very machine I am executing my java code. I am getting IO Exception error stating that I do not have permission to do this operation. So i tried PosixFilePermission to set permission which didn't work either. I have heard there is a workaround using bat or bash command to give admin privilege and execute the batch before deleting the folder. Please let me know if I am doing something wrong or advise on the best workaround.
Note: file.canWrite() didn't throw any exception while checking the
write access. I am using JDK 1.7
String sourcefolder = "C:\Program Files\folder\files";
File file = new File(sourcefolder);
try {
if (!file.canWrite())
throw new IllegalArgumentException("Delete: write protected: "
+ sourcefolder);
file.setWritable(true, false);
//using PosixFilePermission to set file permissions 777
Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
perms.add(PosixFilePermission.OTHERS_WRITE);
Files.setPosixFilePermissions(Paths.get(sourcefolder), perms);
//file.delete();
FileUtils.cleanDirectory(file);
System.out.println("Deleted");
} catch (Exception e) {
e.printStackTrace();
}
You could be getting a failed delete for a number of reasons:- the file could be locked by the file system, you may lack permissions, or could be open by another process etc.
If you're using Java 7 or above you can use the javax.nio.* API; it's a little more reliable & consistent than the [legacy][1] java.io.Fileclasses;
Path fp = file.toPath();
Files.delete(fp);
If you want to catch the possible exceptions:
try {
Files.delete(path);
} catch (NoSuchFileException x) {
System.err.format("%s: no such" + " file or directory%n", path);
} catch (DirectoryNotEmptyException x) {
System.err.format("%s not empty%n", path);
} catch (IOException x) {
// File permission problems are caught here.
System.err.println(x);
}
This is my code to delete you can also refer this:-
import java.io.File;
class DeleteFileExample
{
public static void main(String[] args)
{
try{
File file = new File("C:\\JAVA\\1.java");
if(file.delete()){
System.out.println(file.getName() + " is deleted!");
}else{
System.out.println("Delete operation is failed.");
}
}catch(Exception e){
e.printStackTrace();
}
}
}
[1]: http://docs.oracle.com/javase/tutorial/essential/io/legacy.html
It appears you need to perform an operation running as Administrator. You can do this from Java using a command line
Process process = Runtime.getRuntime().exec(
"runas /user:" + localmachinename + "\administrator del " + filetodelete);
You need to read the output to see if it fails.
For me see http://technet.microsoft.com/en-us/library/cc771525.aspx

How to delete a file present in some directory in linux programmatically

My aim is to delete a file in some directory present in linux using a java program. I have the following line that does that:
java.lang.Runtime.getRuntime().exec("/bin/rm -f " + fileToDelete.getAbsolutePath());
But I read that using linux commands from java program would be a costlier operation. Could anyone let me know if there is another way of doing this?
How about File#delete()
boolean isFileDeleted = fileToDelete.delete();
You could use a File object, as such:
// initializes your file with your full path (or use your "fileToDelete" variable)
File file = new File("myFile");
// attempts to set the file writable and returns boolean result
System.out.println("Could set file writable: " + file.setWritable(true));
// attempts to delete the file and returns boolean result
System.out.println("Deleted succesfullly: " + file.delete());
Permission / delete operations may throw an unchecked SecurityException.
if(file.exists())
boolean isSuccessful = file.delete();
Try this, it works in my Linux
File f= new File("Path");
try {
java.lang.Runtime.getRuntime().exec("rm -f " + f.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}

trying to execute mysqldump from java app, multiple problems

I am writing a java app that needs to perform mysql dump, and I am using the runtime.exec, based in the when runtime.exec won't article. The code is below:
public int exectuteCommand(){
Runtime rt = Runtime.getRuntime();
logger.debug("exexuting cmd: " + showCommand());
int exit = -1;
try {
Process proc = rt.exec(cmd);
ExtProcessStreamHandler errorHandler = new ExtProcessStreamHandler(proc.getErrorStream(), "ERROR");
ExtProcessStreamHandler outHandler = new ExtProcessStreamHandler(proc.getInputStream(), "OUTPUT");
// kick it off
errorHandler.start();
outHandler.start();
exit = proc.waitFor();
} catch (IOException e) {
logger.error("ERROR!! ~~ executing command " + showCommand(), e);
e.printStackTrace();
} catch (InterruptedException e) {
logger.error("ERROR!! ~~ unexpected return for " + showCommand() + " , returned " + exit, e);
e.printStackTrace();
}
return exit;
}
1) The command that the process returns works in the shell (I'm running this on a mac). The first error I had was an inability to find the mysqldump command. That results in this error:
java.io.IOException: Cannot run program "mysqldump": error=2, No such file or directory
I resolved that by adding the complete path of the file to the command. The $PATH var shows
/usr/local/mysql/bin/mysqldump
as the complete path. How can I make sure my java app has that info?
2) when adding the complete path to the command, I get this error msg:
INFO [Thread-1] (ExtProcessStreamHandler.java:28) - external process ERROR : mysqldump: Couldn't find table: ">"
Here is the code that builds the command array:
return new String[] {MYSQLDUMP_CMD, "-u", USER_DEFAULT, "-p"+ PW_DEFAULT, TEST_DB_NAME,
">", DUMP_LOC};
again, when I copy the command passed to the java app into the shell on my mac, it works. Not sure what I'm doing wrong.
thanks in advance!
It thinks ">" is an argument intended for mysqldump. You are invoking an executable, not evaluating a shell expression. If you want to pipe your output, do it with the outHandler and errorHandler in your code.
An alternative is to invoke a shell and pass the expression you want to evaluate as an argument:
expr = new StringBuilder()
.append(MYSQLDUMP_CMD).append(' ')
.append("-u").append(USER_DEFAULT).append(' ')
.append("-p").append(PW_DEFAULT).append(' ')
.append(TEST_DB_NAME).append(' ')
.append(">").append(' ')
.append(DUMP_LOC)
.toString();
return new String[] {"/bin/bash", "-c", expr};
If your code to build the command array doesn't wrap spaced arguments in single quotes (or if the JDK doesn't do this for you), then modify the StringBuilder statement to create the wrapped quotes for you.
Below Code is worked for me
public static void backup() {
String currentDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd"));
String backupPath = String.format("%s/%s.%s", Helper.BACKUP_PATH, currentDate, "sql");
File backupFile = new File(backupPath);
if (!backupFile.exists()) {
try {
backupFile.createNewFile();
String mysqlCom=String.format("mysqldump -u%s -p%s %s",USER_NAME,PASSWORD,DB);
String[] command = new String[] { "/bin/bash", "-c",mysqlCom};
ProcessBuilder processBuilder = new ProcessBuilder(Arrays.asList(command));
processBuilder.redirectError(Redirect.INHERIT);
processBuilder.redirectOutput(Redirect.to(backupFile));
Process process = processBuilder.start();
process.waitFor();
LOGGER.info("Backup done");
} catch (IOException e1) {
e1.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
LOGGER.info("Database already backuped today");
}
}

How to realize "mklink /H" (hardlinking) in Java?

i want to create a hardlink from a file "C:\xxx.log" to "C:\mklink\xxx.log" .
In cmd it works of course, but i want to write a software for this usecase.
So have to locate the existing file
Then make a hardlink
Then delete the old file
I started to implement but, i just know how to create a file. On google i found nothing about mklink \H for Java.
public void createFile() {
boolean flag = false;
// create File object
File stockFile = new File("c://mklink/test.txt");
try {
flag = stockFile.createNewFile();
} catch (IOException ioe) {
System.out.println("Error while Creating File in Java" + ioe);
}
System.out.println("stock file" + stockFile.getPath() + " created ");
}
There are 3 ways to create a hard link in JAVA.
JAVA 1.7 Supports hardlinks.
http://docs.oracle.com/javase/tutorial/essential/io/links.html#hardLink
JNA, The JNA allows you to make native system calls.
https://github.com/twall/jna
JNI, you could use C++ to create a hardlink and then call it through JAVA.
Hope this helps.
Link (soft or hard) is a OS feature that is not exposed to standard java API. I'd suggest you to run command mklink /h from java using Runitme.exec() or ProcessBuilder.
Or alternatively try to find 3rd party API that wraps this. Also check what's new in Java 7. Unfortunately I am not familiar with it but I know that they added rich file system API.
For posterity, I use the following method to create links on *nix/OSX or Windows. On windows mklink /j creates a "junction" which seems to be similar to a symlink.
protected void makeLink(File existingFile, File linkFile) throws IOException {
Process process;
String unixLnPath = "/bin/ln";
if (new File(unixLnPath).canExecute()) {
process =
Runtime.getRuntime().exec(
new String[] { unixLnPath, "-s", existingFile.getPath(), linkFile.getPath() });
} else {
process =
Runtime.getRuntime().exec(
new String[] { "cmd", "/c", "mklink", "/j", linkFile.getPath(), existingFile.getPath() });
}
int errorCode;
try {
errorCode = process.waitFor();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IOException("Link operation was interrupted", e);
}
if (errorCode != 0) {
logAndThrow("Could not create symlink from " + linkFile + " to " + existingFile, null);
}
}

Categories

Resources