Program adds '\' before ':' when writing .properties file in Java [duplicate] - java

This question already has answers here:
How do you escape colon (:) in Properties file?
(8 answers)
Properties file backslash and semicolon
(4 answers)
Closed 5 years ago.
I'm trying to update my database.properties file in my program. However,
it seems Java is adding additional character on my properties file.
Here's a snippet of my code.
Properties props = new Properties();
String propsFileName = "src/resources/properties/" + "database.properties";
String[] property = new String[4];
property[0] = "database.properties";
property[1] = url.getText();
property[2] = username.getText();
property[3] = password.getText();
try {
FileInputStream configStream = new FileInputStream(propsFileName);
props.load(configStream);
configStream.close();
props.setProperty("jdbc.driverClassName", Commons.driverClassName);
props.setProperty("jdbc.url", property[1]);
props.setProperty("jdbc.username", property[2]);
props.setProperty("jdbc.password", property[3]);
props.setProperty("jdbc.comment", comments.getText());
FileOutputStream output = new FileOutputStream(propsFileName);
props.store(output, null);
output.close();
} catch (IOException ex) {
ex.printStackTrace();
}
I have this output on my console which is to check if I get the string that I wanted,
Properties = org.postgresql.Driver,
jdbc:postgresql://192.168.1.1:1234/db, username,
password, null Program Ran on Fri Jun 23 16:00:37 PHT 2017 by
user=xngapp234
However, in my database.properties file, I'm getting this output.
jdbc.url=jdbc\:postgresql\://192.168.1.1\:1234/db
jdbc.username=username
jdbc.password=password
jdbc.comment=
jdbc.driverClassName=org.postgresql.Driver
It adds '\' before the ':' which always gives me an error. Any help is appreciated.
Thanks!

If you're trying to store and load properties from a Java program, everything is working as supposed! Your code shows that the url is read without the backslashes - just as you stored it.
As Berger writes, this is the normal escaping in java.properties files. This is documented in the Javadoc of Properties.store():
[...] The key and element characters #, !, =, and : are written with a
preceding backslash to ensure that they are properly loaded. [...]
If you try to use the Properties class to write a file to be consumed by a non-Java program, you're out of luck as that's not what this class is intended for. You'll need to use another library for that.
The javadoc states
The Properties class represents a persistent set of properties.
The ".properties"-format is just one representation of a set of properties (with an XML format being another).

Related

Read backslashes from propertyfile [duplicate]

This question already has answers here:
Java Properties backslash
(9 answers)
Closed 4 years ago.
I have a property file: project.properties in which I store some property, such as JAVA_PATH=D:\Application\Java8.
I am trying to read it by Java using FileInputStream.
InputStream input = null;
input = new FileInputStream("D:\\Application\\project.properties");
Properties props = new Properties();
props.load(input);
String javaPath = props.getProperty("JAVA_PATH");
System.out.println("JAVA_PATH : "+javaPath);
The output I am getting is:
JAVA_PATH : D:ApplicationJava8
I understand that Java treats this as an escape character and removes it. But is there any way I can read the property as it is by any kind of massaging?
I want the output as JAVA_PATH : D:\Application\Java8.
The \ needs to be escaped with an additional \ in the .properties file, like so:
JAVA_PATH=D:\\Application\\Java8

Java String.Split while printwriting [duplicate]

This question already has answers here:
How to split a path platform independent?
(6 answers)
How to get the path string from a java.nio.Path?
(2 answers)
Where to use resolve() and relativize() method of java.nio.file.Path class?
(5 answers)
Create a Path from String in Java7
(4 answers)
Recursively list files in Java
(30 answers)
Closed 4 years ago.
I'm currently working on a search output system that searches a directory for a specific phrase in a file, matches it, then outputs it to a log file. I have a problem snippet of code that looks like this:
int j = 0;
for(String currentMatch : lineMatch) {
String[] split = fileList.get(j).toString().split("\\\\");
match.write(split[3] + " : " + currentMatch + "\r\n");
match.flush();
j++;
}
With fileList being an arraylist of the file names with a matching result and filePath being an arraylist of the file path. I used the split[3] to return the name of the the forth folder in this directory that I'm interested in.
The output file then becomes a little funky. This directory in question has roughly 40 unique names, but the log ends up looking like this:
dir1 : matchingline
dir2 : matchingline
dir3 : matchingline
dir3 : matchingline
... (x543)
dir4 : matchingline
And so on. Directory 3 is only supposed to have 88 matching lines and ends up with an additional 455 lines that belong to other directories. Any idea on why this happens? Is it because I'm using an assignment in the middle of a PrintWriter, or am I missing something simple here?
Edit: Variables listed for clarity.
match = Printwriter object used to print to an output.
lineMatch = ArrayList() - contains the directory path of the current matched file
fileMatch = ArrayList() - contains the file name that was matched.
split[3] is used because the matched files are consistently found in the 4th directory in, ex. C:\User\Programs\Programname\
/r/n is used to keep formatting on windows.
This is a personal project, so I'm not too concerned with making it portable.
Edited to add the method used for initializing the arraylist.
public static void addFiles(String dirPath) {
File dir = new File(dirPath);
File[] files = dir.listFiles();
try {
if(files.length == 0) {
emptyFilePath.add(dirPath);
}
else {
for (File currentFile : files) {
if(currentFile.isFile()) {
fileList.add(currentFile);
filePath.add(currentFile.getPath());
}
else if (currentFile.isDirectory()) {
addFiles(currentFile.getAbsolutePath());
}
}
}
}catch(Exception e) {
e.printStackTrace();
}
}
And the code that generates lineMatch:
while(i < fileList.size()) {
File files = new File(filePath.get(i));
Scanner file = new Scanner(files);
try {
while(file.hasNextLine()) {
String currentLine = file.nextLine();
if(currentLine.contains(searchString)) {
lineMatch.add(currentLine);
}
}
}finally {
file.close();
}
i++;
}
There are a number of things that are suspicious about your code.
Are LineMatch and FileList variables? If so, then you should write them like variables, that is, lineMatch and fileList (lowerCamelCase). Doing otherwise confuses readers and syntax highlighters alike.
You use split[3], that looks suspicious.
If you are using split("\\\\") in order to get the directory path parts, beware that your code is non-portable, it will work on Windows only. If you want to split a path into its parts, it's better to use the API.
In order to understand the problem, it would be useful to see how LineMatch and FileList are generated, without that, it's not possible to understand what's going wrong in your code.
If match is a PrintWriter or PrintStream, you should use println() or format("...%n") instead of write(... + "\r\n"). Again, because your code is not portable. On Unix, line endings are \n only, not \r\n.
The actual problem is with your program logic. Your variable lineMatch contains the hits of all files found. Because you don't generate a separate lineMatch for each file, but just a single one for all files. At least that's how it looks like from the code that you've posted so far.
It looks like what you want to program is a simple version of grep (or, on DOS, find). Part of your logic is correct, for example, how you use recursion to descend in to the directory tree. Instead of collecting all matches and then printing, find and print the matches while you're traversing the directory tree.
In general, you will end up with less errors if you avoid global variables. You ran into a problem in the first place because your variables LineMatch and FileList are global variables. Avoid global variables, avoid reusing variables, and also avoid variable re-assignment.

Java FileNotFoundException with Absolute path - Cant Read or Execute, but file exists [duplicate]

This question already has answers here:
Saving path in String
(4 answers)
Closed 6 years ago.
I'm sure this has been answered, but ten different strategies hasn't worked on this issue.
If I use C:\Users\Anny\Dropbox\SocialMediaOcto\instructions\Trees\instructions.txt
as my absolute path for the file, IDEA cannot read or execute from this path. If I take that same path and paste it into windows explorer, it will execute right away. I dont want to focus on a working directory as this file works as the program's configurations file, but replaceing the slashes with backslashes doesnt work, the absolute path still brings me to the file, but IDEA doesnt launch.
I'm at wits end.
public static String generateFileName(String folder){
String filename = "";
List<String> hashtags = new ArrayList<>();
String instructions_file = "C:\Users\Anny\Dropbox\SocialMediaOcto\instructions\Trees\instructions.txt";
//does not return true-true, but can launch file on windows explorer..
System.out.println("FILE EXIST AND EXECUTE?" + new File(instructions_file).getAbsoluteFile().canRead() +" "+new File(instructions_file).getAbsoluteFile().canExecute());
System.out.println(new File(instructions_file).getAbsoluteFile());
//C:\Users\Anny\Dropbox\SocialMediaOcto\instructions\Trees\instructions.txt
BufferedReader br = null;
try {
String sCurrentLine;
br = new BufferedReader(new FileReader(new File(instructions_file).getAbsoluteFile()));
EDIT
After replacing backslashes with forward slashes, the reader still cannot properly read or execute the file.
LOG:
The string prints:
C:/Users/Anny/Dropbox/SocialMediaOcto/instructions/Bees/instructions.txt
java.io.FileNotFoundException: C:\Users\Anny\Dropbox\SocialMediaOcto\instructions\Bees\instructions.txt (The system cannot find the file specified)
Correct url:
String instructions_file = "C:/Users/Anny/Dropbox/SocialMediaOcto/instructions/Trees/instructions.txt";
Because \ is an escape character in Java. If you want to use \ as a character you have to escape it itself.
Correct Url v2:
String instructions_file = "C:\\Users\\Anny\\Dropbox\\SocialMediaOcto\\instructions\\Trees\\instructions.txt";
What you had:
String instructions_file = "C:\Users\Anny\Dropbox\SocialMediaOcto\instructions\Trees\instructions.txt";
is read by java as
"C:{something}sers{something}nny{something}ropbox{something}ocialMediaOcto{something}nstructions\Trees\instructions.txt"
In my oppinion it's much better to use the first approach as it's platform safe.

File.Separator in Properties [duplicate]

This question already has answers here:
Java properties file specs [duplicate]
(2 answers)
Closed 7 years ago.
I am using java.util.Properties. However, it cannot read File.separator inside the config file.
As an example, I add this line to the config file. source.dir = D:/workspace/Temp1\Temp2 (Note that File.separator is used to separate Temp1 and Temp2)
The below line is used to load propertis:
Properties properties = new Properties ();
properties.load(new FileInputStream("configFileAddress"));
The result is: source.dir = D:/workspace/Temp1Temp2 (File.Separator is removed).
Any one knows, how can I fix that?
Replace:
source.dir = D:/workspace/Temp1\Temp2
To:
source.dir = D:\\workspace\\Temp1\\Temp2
This field is initialized to contain the first character of the value
of the system property file.separator. On UNIX systems the value of
this field is '/'; on Microsoft Windows systems it is '\'.

Saving certain text from JTextArea to a file using JFileChooser

I have this text from my JTextArea:
Getting all .mp3 files in C:\Users\Admin\Music including those in subdirectories
C:\Users\Admin\Music\Sample Music\Kalimba.mp3
C:\Users\Admin\Music\Sample Music\Maid with the Flaxen Hair.mp3
C:\Users\Admin\Music\Sample Music\Sleep Away.mp3
Finished Searching...
I want to save only this part:
C:\Users\Admin\Music\Sample Music\Kalimba.mp3
C:\Users\Admin\Music\Sample Music\Maid with the Flaxen Hair.mp3
C:\Users\Admin\Music\Sample Music\Sleep Away.mp3
Unfortunately I can't with the code below:
JFileChooser saveFile = new JFileChooser("./");
int returnVal = saveFile.showSaveDialog(this);
File file = saveFile.getSelectedFile();
BufferedWriter writer = null;
if (returnVal == JFileChooser.APPROVE_OPTION)
{
try {
writer = new BufferedWriter( new FileWriter( file.getAbsolutePath()+".txt")); // txt for now but needs to be m3u
searchMP3Results.write(writer); // using JTextArea built-in writer
writer.close( );
JOptionPane.showMessageDialog(this, "Search results have been saved!",
"Success", JOptionPane.INFORMATION_MESSAGE);
}
catch (IOException e) {
JOptionPane.showMessageDialog(this, "An error has occured",
"Failed", JOptionPane.INFORMATION_MESSAGE);
}
}
With the code above, it saves everything from the JTextArea. Can you help me?
P.S. If possible, I want to save it as an M3U Playlist.
I'm assuming searchMP3Results is the JTextArea containing the text. In this case you could just get the text as a String using searchMP3Results.getText() and run the result through a regular expression looking for file paths. An example regex for Windows paths is on this question java regular expression to match file path. Unfortunately this ties your application to Windows, but if that's acceptable then you're good to go otherwise you should detect the OS using system properties and select the correct regex.
As far as the m3u you should just be able to export the directory paths (one per line). Extended m3u files (using the header #EXTM3U) require additional information, but you should be able to get away with the simple version.
Update: Added code
Update 2: Changed regex to a modified version of path regex (vice file) and now run it against each line instead of performing a multiline assessment
String text = searchMP3Results.getText();
StringBuilder output = new StringBuilder();
for ( String s : text.split("\n") ) {
if ( java.util.regex.Pattern.matches("^([a-zA-Z]:)?(\\\\[\\s\\.a-zA-Z0-9_-]+)+\\\\?$", s) ) {
output.append(s).append("\n");
}
}
This code splits the input into an array of lines (you may want to use \r\n instead of just \n) and then uses a regex to check if the line is a path/filename combination. No further checks are performed and the path/filename is assumed to be valid since it's presumably coming from an external application. What I mean is the regex doesn't check for invalid characters in the path/filename nor does it check for the file existence though this would be trivial to add.

Categories