We are having wierd issues when working with paths in Java for files. The thing is that sometimes, when working in Windows, operations with files created with slashes and backslashes in their paths are failing. As a rule we are replacing slashes by backslashes bu we cannot identify why sometimes the operation fails and others not.
Specifically the operation is file.delete(). It does not throw any kind of Exception, if simply fails.
You shouldn’t use File.delete() for exactly the reason you have described; it doesn’t provide you with a meaningful response if the operation fails.
Use Files.delete(Path) or Files.deleteIfExists(Path) to delete a file (denoted by a Path, see Paths.get(String…) and File.toPath()) as these methods will throw a meaningful IOException on failure whereas only the latter returns a boolean which will indicate success or non-existence but all other conditions are flagged with an exception.
There are indeed functions in the Windows API which silently handle slashes as separators but since it is not specified which Java API methods will use which native functions, you can’t rely on any particular behavior in this regard. You should always use the separator as indicated by File.separatorChar or FileSystems.getDefault().getSeparator() when using the nio API.
File.delete does not throw an exception if it fails; instead it returns a boolean that indicates whether the delete has failed or not. From the Javadoc:
Returns true if and only if the file or directory is successfully deleted; false otherwise
If you want an exception when the delete fails, you need to raise it yourself:
if (!myfile.delete()) {
throw new IOException("Couldn't delete file " + myfile.getPath());
}
Unless you escape backslashes, Java treats them as escape codes. This is how newline (\n) and tab (\t) work, for example.
From the JavaDoc on Characters and Escape Sequences:
A character preceded by a backslash (\) is an escape sequence and has special meaning to the compiler.
So what's happening is that your file path is probably something that's being treated as an escape sequence. That link has some detail as to what kinds of escape codes there are.
So if you just did this:
File.delete("c:\this.txt")
// Converted to "c: his.txt" (because of the tab)
I'd recommend either doubling up the backslashes (\\) or going to all forward slashes, if you can.
Related
The return value of a value from getPath() from the File Class is something like this
"C:\Users\Daniel\Desktop\ASDF.mp3".
To use the Desktop class from java to play a file, the path would have to be fed into a file, with a path similar to
"C:\\Users\\Daniel\\Desktop\\ASDF.mp3"
Since the \ is a reserved character(From my understanding) to make a new file you must use a double backslash to dictate that it is a file. My problem is that when I try to get the path I need to transform it into a double slash version. The .replaceAll() method doesn't allow for '\' since it's a reserved character but the .replace() method does.
To work around this would I just have to loop through to find all instances and replace them one at a time? Or is there a simpler work around? Also I would like to know if I am receiving this error due to it being a reserved character, or if I am completely wrong.
The two strings above are actually exactly the same.
When Java or other language outputs a string it only displays one slash '\', but when you are typing the string into double quotes you need double backslash '\\' so the Java parser knows it's one slash. Backslash is used for many other escape characters, so this is only way parser will know.
(Even when typing this answer, I needed 4 backslashes to make only 2!
I've looking through How to escape the equals sign in properties files but didn't find my answer.
I have a Java Properties File that includes sets such as:
SOME_KEY = SOME_VALUE
This is normal. However, some of the values actually contain escape/control characters, such as URL's. This properties file is to be hand edited by a user on a rare occasion. I want the user to be able to simply paste in a URL and not worry about special rules, etc.
So I have this showing in my file now:
SOME_KEY = http://www.example.com/something.asp?some=
where some= is the base of dynamic URL where something after the = will cause the URL to respond differently.
From reading http://docs.oracle.com/javase/6/docs/api/java/util/Properties.html it doesn't seem to make mention of needing to escape any escape/control characters after the first unescaped = or : is encountered, but I need/want to make sure.
I know that if my KEY had one of those characters present, then it would have to be escaped otherwise it'd be misread... such as:
SOME\=KEY = SOME_VALUE
Would make for a literal SOME=KEY as the key value.
In this above situation, excluding the obvious escaping of the KEY, is it necessary to hand-escape the values?
After the first = without escape, no.
If you use eclipse, you might want install the JBoss Tools Properties Editor. You not need to worry about escaping values manually as you mention SOME=KEY or Unicode. However, the pluging escapes the characters to avoid reading and coding problems.
http://www.jboss.org/tools
First look at the code below
public static void main(String args[])
{
System.out.println(new Stringtest().test("The system has saved your payment under transaction number \369825655."));
}
private String test(String aa)
{
return aa.substring(58);
}
so logically this method should print 369825665. But it is printing 9825655 because of that backslash. Now I want the whole number. What should I do. I can not change the \ to \\ because the text is coming from a website.
\ is an escape character. You need to escape the escape character.
System.out.println(new Stringtest().test("The system has saved your payment under transaction number \\369825655."));
For more on escape sequences, see this Oracle document. Essentially the backslash tells the system that the character(s) after it should be interpreted in a special manner (not simply as plain text). When you escape the escape, it gets treated specially as well... as plain text, instead of as an escape character.
It can get confusing sometimes but is intuitive once you learn the core concepts.
EDIT: If you can't control the format the String comes to you in, you might be out of luck. I've been debugging this in Eclipse, and it seems like as soon as you create your String with that, the escape character gets processed and you lose the first two digits of your transaction number. You may need to get your database guys (or whomever formatted this terrible String) to change their implementation for you to do what you need to do. The Eclipse debugger suggests this, at least.
It just so happens that, apparently, \36 processes fine and gets interpreted as another ASCII character that doesn't show up. But in other cases, this will likely throw an Exception as an invalid escape sequence.
In my own testing, it seems that as soon as the String literal is declared/created, the loss of information occurs. So there will be no way to recover it after that to my knowledge.
Debug Screenshot
Try \\369825655 - basically it escapes the escape sign. Then replace all \ characters with empty characters.
Add another backslash (escape character)
ArrayList System.out.println(new Stringtest().test("The system has saved your payment under transaction number \\369825655."));
logpath = LoggerUtils.getProperties().getProperty("log.path");
System.out.println("logpath: " + logpath);
The above code returns:
logpath: C:UsersMauriceDesktopLogs
In the properties file is:
log.path C:\Users\Maurice\Desktop\Logs
How do I retain the file separators? I want this to work on Linux as well and not just Windows.
Actually, you need to put this in the property file:
log.path C:\\Users\\Maurice\\Desktop\\Logs
See this:
http://docs.oracle.com/javase/6/docs/api/java/util/Properties.html
more precisely the load method:
http://docs.oracle.com/javase/6/docs/api/java/util/Properties.html#load(java.io.Reader)
Scroll down a bit and you will see this among other things:
The method does not treat a backslash character, \, before a non-valid escape character as an error; the backslash is silently dropped. For example, in a Java string the sequence "\z" would cause a compile time error. In contrast, this method silently drops the backslash. Therefore, this method treats the two character sequence "\b" as equivalent to the single character 'b'.
Backslash \ is an escape character that is silently dropped otherwise.
In a property file, you need to either use forward slashes:
C:/Users/Maurice/Desktop/Logs
Or, escaped backslashes:
C:\\Users\\Maurice\\Desktop\\Logs
You need to escape the slashes as they are special characters. See: Java Properties backslash
The Java properties file format dictates that the backslash character ("\") escapes the character that follow it, so to get a literal windows path you must have:
logpath: C:\\Users\\Maurice\\Desktop\\Logs
However, Java will convert path separator characters for you automatically to suit the runtime platform, so you can avoid this nuisance by always using forward slashes:
logpath: C:/Users/Maurice/Desktop/Logs
You can store the Properties to file first, then load it again to use. Properties will take care of escaping/ unescaping anything.
I have to create a file based on a string provided to me.
For this example, let's say the file name is "My file w/ stuff.txt".
When Java creates the file using
File file = new File("My file w/ stuff.txt")
Even though the default windows separator is '\', it assumes that the '/' slash is a file separator. So a future call to file.getName() would return " stuff.txt". This causes problems for my program.
Is there any way to prevent this behaviour?
According to this Wikipedia page, the Windows APIs treat / as equivalent to \. Even if you somehow managed to embed a / in a pathname component in (for example) a File object, the chances are that Windows at some point will treat it as a path separator.
So your options are:
Let Windows treat the / as it would normally; i.e. let it treat the character as a pathname separator. (Users should know this. It is a "computer literacy" thing ... for Windows users.)
As above, but with a warning to the user about the /.
Check for / AND \ characters, and reject both saying that a filename (i.e. a pathname component) cannot contain pathname separators.
Use some encoding scheme to encode reserved characters before attempting to create the files. You must also then apply the (reverse) decoding scheme at all points where you need to show the user their "file name with slashes".
Note: if the user can see the actual file paths (e.g. via a command shell) you can't hide the encoding / decoding from them. Arguably, that is worse than the "problem" you were trying to solve in the first place.
There is no escaping scheme that the Windows OS will accept for this purpose. You would need to use something like % encoding; e.g. replace / with %2F. Basically you need to "hide" the slash character from Windows by replacing it with other characters in the OS-level pathname!
The best option depends on details of your application; e.g. whether you can report problems to the person who entered the bogus filename.
If a string is being provided to you (from an external source), it doesn't sound like you can prevent that string from containing certain characters. If you have some sort of GUI to create the string, then you can always restrict it there. Otherwise, whatever method is creating your file should check for a slash and either return an error or handle it as you see fit.
Since neither forward nor backward slashes are allowed in windows file names, they should be cleaned out of the Strings used to name files.
Well, how could you stop it being a folder separator? It is a folder separator. If you could just decide for yourself what was and what wasn't a folder separator, then the whole system would come crashing down.