How to realize "mklink /H" (hardlinking) in Java? - 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);
}
}

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);
}

How to run application with parameters from within java application on mac osx

I am writing a small java application to load ZDoom with custom wad files on mac osx and am having trouble executing the command.
I have generated a string within the application that will run ZDoom and load the custom wad, I have tested this by copy-pasting the string from the netbeans breakline debugger and running it directly in terminal.
When I run the code through my application ZDoom does load up but it does so without the custom wad so I believe it is executing without it's arguments.
I have tried two different techniques to run the command:
private void loadZdoom() {
// get selected wad
String wad = (String) wadListComboBox.getSelectedItem();
ProcessBuilder builder = new ProcessBuilder(defaultZdoomInstallPath + "/Contents/MacOS/zdoom", "-file", defaultZdoomWadsPath.replace(" ", "\\ ") + "/" + wad);
builder.redirectErrorStream(true);
try {
Process p = builder.start();
} catch (IOException ex) {
}
}
And
private void loadZdoom() {
// get selected wad
String wad = (String) wadListComboBox.getSelectedItem();
String runCommand = defaultZdoomInstallPath + "/Contents/MacOS/zdoom " + "-file " + defaultZdoomWadsPath.replace(" ", "\\ ") + "/" + wad;
try {
Runtime runTime = Runtime.getRuntime();
Process process = runTime.exec(runCommand);
} catch (IOException e) {
}
}
What am I doing wrong here?
I figured out what the problem was, I was escaping the space in the path to the wad file as you need to do this in terminal but it seems this is unnecessary in JAVA. All is working as expected now :)

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

Using php-cgi with webserver in android

I found that we can run Phpcgi on android by going to this site.I have created a web server in android it works fine and i have installed Php cgi and want to ask that how can i link both so that i can run php scripts as well as HTML pages.Any help will be appreciated.
Update:
In my Request Processor the out is sent like this:
contentType = guessContentTypeFromName(filename);
Date now = new Date( );
out.write("Date: " + now + "\r\n");
out.write("Server: JHTTP/1.0\r\n");
out.write("Content-length: " + theData.length + "\r\n");
out.write("Content-type: " + contentType + "\r\n\r\n");
out.flush( );
guessConte....()
if (name.endsWith(".php")) {
String pathToPhpExecutable = Environment.getExternalStorageDirectory() + "/data" + "/php-cgi";
String phpFile ="" + "/php/myPhpFile.php";
Process process = null;
try {
process = new ProcessBuilder()
.command(pathToPhpExecutable, phpFile)
.redirectErrorStream(true)
.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
} finally {
process.destroy();
}
You can use the Process and ProcessBuilder classes to create and execute an command. Keep in mind that depending on the process you want to execute, you may require root permissions and it won't work on non-rooted Android devices.
String pathToPhpExecutable = getFileDir() + "/php-cgi";
String phpFile = getFileDir() + "/php/myPhpFile.php";
Process process = new ProcessBuilder()
.command(pathToPhpExecutable, phpFile)
.redirectErrorStream(true)
.start();
try {
InputStream in = process.getInputStream();
// Read the input stream and i.e. display the results in a WebView
} finally {
process.destroy();
}
Don't be confused by the naming. According to the Process documentation getInputStream() returns the output of the stream connected to the std::out. This will return Code (Json, HTML, plain text) generated by the PHP.
However, chances are you will need root for it to work. Or that the files won't have execution permission (x in Linux) when you unpack them from your APK. But calling chmod or chown (if it's assigned to the wrong user name) will most likely require an rooted Android devices.
Process | Android Developers

ProcessBuilder with gunzip does not work

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.

Categories

Resources