reconstructing a file path in java - java

I have a file path location as such:
Properties readProp = \\192.168.41.84\dev\config\dev\config.properties
how can I manipulate it so I remove the portion of config.properties
and replace it with test\config.properties
so the new Properties location would be:
Properties readProp = \\192.168.41.84\dev\config\dev\test\newconfig.properties
?
thanks for your time and effort

Make sure you escape any backslashes you have as you build the string.
String path = "\\\\192.168.41.84\\dev\\config\\dev\\config.properties";
System.out.println(path);
int lastBackSlash = path.lastIndexOf("\\");
//+1 to include lastBackSlash
String newPath = path.substring(0, lastBackSlash + 1) + "test" + path.substring(lastBackSlash);
System.out.println(newPath);
Prints
\\192.168.41.84\dev\config\dev\config.properties
\\192.168.41.84\dev\config\dev\test\config.properties
This article like this is also decent read. Treating paths as strings can be dangerous.
http://twistedoakstudios.com/blog/Post4872_dont-treat-paths-like-strings
However, if your careful, know what how your string functions behave(or look them up), and you don't have off by 1 errors... then treating the paths like strings should be pain free. But you will have no guarantee that the path is valid... while a path builder library would give you that assurance.

Related

Convert Windows style path into unix path in java code

I am working in a java code that was designed to run on windows and contains a lot of references to files using windows style paths "System.getProperty("user.dir")\trash\blah". I am in charge to adapt it and deploy in linux. Is there an efficient way to convert all those paths(\) to unix style (/) like in "System.getProperty("user.dir")/trash/blah". Maybe, some configuration in java or linux to use \ as /.
My approach is to use the Path object to hold the path information, handle concatenate and relative path. Then, call Path's toString() to get the path String.
For converting the path separator, I preferred to use the apache common io library's FilenameUtils. It provides the three usefule functions:
String separatorsToSystem(String path);
String separatorsToUnix(String path);
String separatorsToWindows(String path)
Please look the code snippet, for relative path, toString, and separator changes:
private String getRelativePathString(String volume, Path path) {
Path volumePath = Paths.get(configuration.getPathForVolume(volume));
Path relativePath = volumePath.relativize(path);
return FilenameUtils.separatorsToUnix(relativePath.toString());
}
I reread your question and realize you likely don't need help writing paths. For what you're trying to do I am not able to find a solution. When I did this in a project recently I had to take time to convert all paths. Further, I made the assumption that working out of the "user.home" as a root directory was relatively sure to include write access for that user running my application. In any case, here are some path problems I addressed.
I rewrote the original Windows code like so:
String windowsPath = "C:\temp\directory"; //no permission or non-existing in osx or linux
String otherWindowsPath = System.getProperty("user.home") + "\Documents\AppFolder";
String multiPlatformPath = System.getProperty("user.home") + File.separator + "Documents" + File.separator + "AppFolder";
If you're going to be doing this in a lot of different places, perhaps write a utility class and override the toString() method to give you your unix path over and over again.
String otherWindowsPath = System.getProperty("user.home") + "\Documents\AppFolder";
otherWindowsPath.replace("\\", File.separator);
Write a script, replace all "\\" with a single forward slash, which Java will convert to the respected OS path.

Concatenating Strings in Java generates between-in null

This question looks like very similar to: Concatenating null strings in Java
But my issue is some different.
I want to build an absolute path to a file:
String path = properties.get("path"); // returns /home/myuser/relativepath/ , ends with bar /
String file = currentFile; // currentFile values "file.txt"
String result = path + file; // this results in /home/myuser/relativepath/nullfile.txt
Why is there than 'null' text? That's the reason my application does not work now.
I have review it in Windows and Linux.
In Windows it works perfectly.
In Linux, I have this issue.
I uploaded properties file and then, edited with vi command.
Maybe is this the problem?
Shouldn't I use this way to generate an absolute path, and use File.Separator property in Java?
EDIT: I have post my final right answer with detailed steps. I hope it would be useful.
My bet (though I have not seen Java behave this way) is there's a null-ish character (such as a carriage return) of some sort in your properties file which Windows handles at the OS level so Java/Properties doesn't see it.
As a first pass, try printing the length and last few characters of your path string, e.g.:
for(int i = Math.max(0, path.length()-5); i < path.length(); i++) {
System.out.print(path.charAt(i)+":"+((int)path.charAt(i))+" ");
}
System.out.println(path.length());
Willing to bet the last character, on Linux, is not what you'd expect. The right fix would then be to clean up your properties file so that it's compatible on both OSes.
Well, the complete and detailed steps to fix my issue are these (maybe any of them could not be necessary, but I prefer to write them all):
Create config file in Linux with vi, emacs, ... (not upload file from Windows).
Edit file with vi, emacs... At the end of each path, do not include directory separator character ( / ).
Check variables before contatenate them. Make sure they don't have any space and other unexpected character.
Concatenate variables with:
String result = path + File.separator + file;
I hope this would be useful. Thank you all for your suggestions.
Regards
What do you expect?
Yo´re doing a String result = path + result;
int a = 1 + a would be similar... don´t use a variable to init itself.
(That can´t be your code in the first place, if you´re getting this output.)
result is path+file :
String path = properties.get("path");
String file = currentFile;
String result = path + file;
^
change here
the result is: /home/myuser/relativepath/file.txt

File path names for Windows and Linux

Below is a path to my Windows directory. Normally the path should have \ instead of // but both seem to work.
String WinDir = "C://trash//blah//blah";
Same for a Linux path. The normal should have a / instead of //. The below and above snippet work fine and will grab the contents of the files specified.
String LinuxDir = "//foo//bar//blah"
So, both use strange declarations of file paths, but both seem to work fine. Elaboration please.
For example,
File file = new File(WinDir);`
file.mkdir();`
Normally, when specifying file paths on Windows, you would use backslashes. However, in Java, and many other places outside the Windows world, backslashes are the escape character, so you have to double them up. In Java, Windows paths often look like this: String WinDir = "C:\\trash\\blah\\blah";. Forward slashes, on the other hand, do not need to be doubled up and work on both Windows and Unix. There is no harm in having double forward slashes. They do nothing to the path and just take up space (// is equivalent to /./). It looks like someone just did a relpace of all backslashes into forward slashes. You can remove them. In Java, there is a field called File.separator (a String) and File.separatorChar (a char), that provide you with the correct separator (/ or \), depending on your platform. It may be better to use that in some cases: String WinDir = "C:" + File.separator + "trash" + File.separator + "blah" + File.separator + "blah";
With java.nio.path, you even better get an independent OS path without any concern about path delimiter.
public class PathsGetMethod {
public static void main(String[] args) {
Path path = Paths.get("C:\\Users\\conta\\OneDrive\\", "desktop", "data");
System.out.println(path);
//C:\Users\conta\OneDrive\desktop\data
}
}

Java os path operations, joins, and moving up levels

I have 2 related questions regarding files, and the File class in Java.
I gather the best practice way to build a path - and have it OS agnostic - is like this:
File file = new File("dir" + File.separator + "filename.ext");
My first question is, "Is there a Java equivalent of python os.path.join function built into Java?"
i.e. Is there a function where I can do something like this:
String path = some_func("arbitrary", "number", "of", "subdirs", "filename.ext");
I suspect if such a thing exists, I may need to pass an Array of Strings to the function, rather than an arbitrary number of args, but the above would be ideal.
But regardless of the answer to the question above, my second question is, "is there a built in way to move a level up when specifying a path?"
i.e. Is the correct way, to do something like this:
String rel_path = ".." + File.separator + "filename.ext";
Or is there something like this:
String rel_path = File.level_up + File.separator + "filename.ext";
Cheers all!
I gather the best practice way to build a path - and have it OS agnostic - is like this:
File file = new File("dir" + File.separator + "filename.ext");
Or like this (see the API documentation on the constructors of java.io.File):
File file = new File("dir", "filename.ext");
Note that this takes only two parameters - the name of the parent directory and the filename (not an arbitrary list of subdirectories).
You're looking for java.nio.file.Paths.get():
Path path = Paths.get("arbitrary", "number", "of", "subdirs", "filename.ext");
Note that gives you a Path rather than a File, if you really need a File then call toFile() on the Path.
Note: This is all new stuff in Java 7.
Not that I know of for Java 6, but you could use Apache's StringUtils to achieve the same effect:
StringUtils.join(components, File.separator)
As above, where components is an Iterable or an array of your file path components.
e.g. String path = StringUtils.join(new String[] {"foo", "bar"}, File.separator);
On your first question, Jesper is right imo that java.nio.Pages.get() is best if you're using java 7.
On the second part of your question, consider using:
file.getParentFile().getName();
To navigate to the parent of the given file (or dir).

File.mkdir is not working and I can't understand why

I've this brief snippet:
String target = baseFolder.toString() + entryName;
target = target.substring(0, target.length() - 1);
File targetdir = new File(target);
if (!targetdir.mkdirs()) {
throw new Exception("Errore nell'estrazione del file zip");
}
doesn't mattere if I leave the last char (that is usually a slash). It's done this way to work on both unix and windows. The path is actually obtained from the URI of the base folder. As you can see from baseFolder.toString() (baseFolder is of type URI and is correct). The base folder actually exists. I can't debug this because all I get is true or false from mkdir, no other explanations.The weird thing is that baseFolder is created as well with mkdir and in that case it works.
Now I'm under windows.
the value of target just before the creation of targetdir is "file:/C:/Users/dario/jCommesse/jCommesseDB"
if I cut and paste it (without the last entry) in windows explore it works...
The path you provide is not a file path, but a URI.
I suggest you try the following :
URI uri = new URI("file://c:/foo/bar");
File f = new File(uri).
It looks, to me, as if the "file:/" at the beginning is the problem... Try getAbsolutePath() instead of toString().
The File constructor taking a String expects a path name. A path name is not an URI.
Remove the file:/ from the front of the String (or better yet, use getPath() instead of toString()) to get to the path you need.

Categories

Resources