Java - Escaped backslashes being taken literally when writing to file - java

I want to store a URL in a properties file. This is the URL:
jdbc\:sqlserver\://dummydata\\SHARED
When programming this in Java, I obviously need to escape the backslashes. So my code ends up looking like this
properties.setProperty("db", "jdbc\\:sqlserver\\://dummydata\\\\SHARED");
The issue with this is that the properties file is saving the String URL and including the backslashes used for escaping, which is an incorrect URL. I was hoping that Java would interpret the backslashes used for escaping so that only the correct URL is saved. Is there a way to achieve this?

You're correct that a property value with : needs to escape the colons in a .properties text file, but you're not writing that text file directly.
You are giving the value to a Properties object using setProperty(), and presumably writing that to a text file using store(), and the store() method will escape the values as needed for you.
You should give the value you want to Properties, and forget about the encoding rules of the text file. Properties will handle all needed encoding. Since the value you want to give is jdbc:sqlserver://dummydata\SHARED, you write a string literal "jdbc:sqlserver://dummydata\\SHARED"
Example
String db = "jdbc:sqlserver://dummydata\\SHARED";
System.out.println(db); // To see actual string value
Properties properties = new Properties();
properties.setProperty("db", db);
try (FileWriter out = new FileWriter("test.properties")) {
properties.store(out, null);
}
Output
jdbc:sqlserver://dummydata\SHARED
Content of test.properties
#Tue Jun 11 11:54:24 EDT 2019
db=jdbc\:sqlserver\://dummydata\\SHARED
As you can see, the store() method has escaped the : and \ for you.
If you save the properties as an XML file instead, there's no need to escape anything, and Properties won't.
Example
try (FileOutputStream out = new FileOutputStream("test.xml")) {
properties.storeToXML(out, null);
}
Content of test.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="db">jdbc:sqlserver://dummydata\SHARED</entry>
</properties>

Properties.store() escapes backslashes, there is no way around it. I guess my first question is why is this an issue? Are you reading the file in any other way than using Properties.load(). If not they you don't need to worry about it as the load function will remove the escape characters.
properties.load(file);
System.out.println(properties.get("db"));
// output: jdbc\:sqlserver\://dummydata\\SHARED
As an aside are you sure you the URL is correct? Shouldn't you be storing it as properties.setProperty("jdbc:sqlserver://dummydata\SHARED")?

In the documentation for load, it says the following:
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'.
This means that two backslashes will be treated as a single one because it's not a valid escape sequence. Loading this string should work just fine:
C:\\path\\to\\file

Related

Single Backslash Changing to Doublebackslash in Property file

Hi this post is related to my old post. But in this I have achieved much.
I am using FileBasedConfigurationBuilder class of Apache common configuration API for updating property file in java. Below is my code:
FileBasedConfigurationBuilder<PropertiesConfiguration> builder = new FileBasedConfigurationBuilder<PropertiesConfiguration>(
PropertiesConfiguration.class)
.configure(new Parameters().properties().setFileName("test.properties")
.setThrowExceptionOnMissing(true));
PropertiesConfiguration config = builder.getConfiguration();
config.setProperty("Id", "3");
builder.save();
System.out.println("config.properties updated Successfully!!");
Now one of my key have value like
C\://ABC.net\\:1010.
After modification it becomes
C\\://ABC.net\\:1010. Means it single backslash is converting to two single backslash. Previously I was using common configuration jar 1.10 it that forwardslash also getting change. Now I have used common configuration version
commons-configuration2-2.0.jar. By this version only problem in backslash.
Can any one suggested how to avoid this? I need that after modification single backslash should not convert to doublebackslash.Please note that I don't want to change the property file.
I was following below post to reach till here.
PropertiesConfiguration - Using "/" in Property value
In a properties file, the : character is escaped with a single backslash, which is what seems to be happening in your question.
See this question How do you escape colon (:) in Properties file?
which points to the Properties documentation

Removing escape characters when saving a Path in Properties JavaFX

I am saving the path of a file as using Properties in Java into a config file.
this.adb = adb.getAbsolutePath();
this.prop.setProperty("adb", this.adb);
//save config to project root folder
this.prop.store(new FileOutputStream("config"), null);
The contents of config file after saving are:
adb=C\:\\Program Files\\Genymobile\\Genymotion\\tools\\adb.exe
How do I save it without the escape characters so that it can be easy for a user to modify the path manually without having to type in escape characters.
I also tried to save the config file manually without using escape characters, but the program read the property as:
C:Program FilesGenymobileGenymotion oolsadb.exe
And the code for reading properties from the config file is:
prop.load(new FileInputStream("config"));
this.adb = prop.getProperty("adb");
java.util.Properties.store uses backslash to escape special characters (e.g. equal sign in properties keys), so a literal backslash itself will need to be escaped \\. If this behaviour is not what you want, don't use java.util.Properties, roll out your own utility Properties class it should be a simple exercise. If your not sure what an escape character is check this Wikipedia page.
The relevant code in Properties class (saveConvert method)
if (aChar == '\\') {
outBuffer.append('\\'); outBuffer.append('\\');
continue;
}

Map invalid character to valid character while creating a file and back to original name when read filename

I need to map invalid characters to some other characters like "/" to "_" (forward slash to underscore) while creating a file because file name do not allowed to put slashes, question, double quotes etc.
Suppose I have
String name = "Message Test - 22/10/2016";
Now I want to write a file by using above string but it gives error because of slashes.
So I want to map slash like all the invalid characters to any other characters while writing a file. After writing, I need to read all the names of the files & show on the page.
SOMEHOW I MAP THE CHARACTERS, SO FILE NAME WOULD BE
Message_Test_-_22-10-2016
When I show it on web I need to return file name as the original name like
Message Test - 22/10/2016
I am using java. Can anyone help me out of this how can I start writing this approach or Is there any api for it or Is there any other approach.
I don't want to use database to co-related alias file name with original file name
I need to map invalid characters to some other characters like "/" to "_"
It is not enough robust since it supposes that you never use the _ character in the filename.
If you use it, how to know if a file stored as my_file should be displayed as my_file or my/file in your application.
I think that a more reliable way would be to have a file (JSON or XML for example) that stores the two properties for each file :
the stored filename
the visual name representing it in your application
It demands an additional file but it makes things really clearer.
You can use a map to store the mappings:
E.g.
Map<Character,Character> map = new HashMap<Character,Character>();
map.put('/','_');
And then replace the characters in 1 traversal:
for(int i=0;i<str.length();i++){
char c = str.charAt(i);
if( map.containsKey(c) )
str.replace(c,map.get(c));
}

Not able to read Properties File using Backward Slash

I Am not able to read Properties File using Java.It Means In this Properties File Backward Slash is not working.It is showing like ,this destination :C:Usersxxx.a
String filename="D://Desktop//xxx.properties";
is = new FileInputStream(filename);
Properties prop=new Properties();
prop.load(is);
System.out.println("destination :"+prop.getProperty("destination"));
Property File is the :
destination=C:\Users\xxx.a\
Result is showing
destination :C:Usersxxx.a
But I want to show destination :C:\Usersxxx.a\
Can You Please suggest Me?
\ is an Escape character.
forward slash / is used as path separator in Unix environment.
Back slash \ is used as path separator in Windows environment.
So, You need to use \\ or / as path separator. You can not directly use \ in java. Since, it is an escape character.
So,You need to make changes in your properties file to make your program work.
Use either / or \\ as path separator in your properties file.
In your case you want to show as C:\Users\xxx.a\.
So, use C:\\Users\\xxx.a\\ in your properties file to get output as C:\Users\xxx.a\
The \ character is used as an "escape character" in many programming languages. It gives a special meaning to the next character in the text. For example, \n encodes the special character "new-line".
Use \\ instead of \. This indicates to the parser that you mean the actual symbol, not an escape character. For example, your property value would be:
destination=C:\\Users\\xxx.a\\
You need to add two slashes to your properties file like this:
destination=C:\\Users\\xxx.a\\
The other way is to swap the slashes in the properties file:
destination=C:/Users/xxx.a/
A \ is an escape character so it is removed. Adding two slashes escapes the first so only one is left.
You can store it in D:/Desktop/xxx.properties as
destination=C:/Users/xxx.a/
and show it with a single backslash
String fileName = prop.getProperty("destination");
System.out.println("destination: " + fileName); // shows: C:/Users/xxx.a/
System.out.println("destination: " + Paths.get(fileName)); // shows: C:\Users\xxx.a

how to replace a backslash in some lines of a text in Ant

Using
<replaceregexp byline="true" flags="g" file="${someFIle}"
match = "[\\]"
replace = "/"/>
I can easily replace all the \ with /.
But
Suppose the text is:
Other A\B\C
Some C\D\E
Other ...
Other ...
...
How to replace the "\" with "/" in the second line which has prefix "Some", but not other lines:
Other A\B\C
Some C/D/E
...
replaceregexp does not have options to skip lines.
Your problem cannot be merely solved by a single regex. You need to do something more complex.
1) Read properties only with the specified prefix and save them to variable. This can be done with propertyregex.
2) Read all other properties and save them somewhere.
3) Replace \ with whatever you want in the properties which contain the prefix.
4) Write the modified properties with the properties without the prefix into a file replacing the original file.
5) Enjoy :-)
Try to do these steps one by one. If you still have questions let me know.

Categories