I am loading property from file, the property contains path (Windows path) and I need to normalize it to create usable path. The problem is that I can't replace "\".
Here is my test class:
public class PathUtil {
public static String normalizeEscapeChars(String source) {
String result = source;
result = result.replace("\b", "/b");
result = result.replace("\f", "/f");
result = result.replace("\n", "/n");
result = result.replace("\r", "/r");
result = result.replace("\t", "/t");
result = result.replace("\\", "/");
result = result.replace("\"", "/\"");
result = result.replace("\'", "/'");
return result;
}
public static void main(String[] args) {
try(FileInputStream input = new FileInputStream("C:\\Users\\Rakieta\\Desktop\\aaa.properties")) {
Properties prop = new Properties();
prop.load(input);
System.out.println(PathUtil.normalizeEscapeChars(prop.getProperty("aaa")));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Here property file:
aaa=Intermix\koza , intermix\trace
Actual output is :
Intermixkoza , intermix/trace
Needed output is :
Intermix/koza , intermix/trace
Any suggestions?
When I copied your code my IDE threw an error saying \k is not a valid escape character. So I removed the whole line.
result = result.replace("\k", "/k");
// I have not seen that escape character (Correct me if I am wrong)
And my output was
aaa=Intermix/koza , intermix/trace
or you try what Connor said that is
result = result.replace("\\k", "/k");
// This code is replacing \k with /k in Intermix\koza. So it is kinda hard coded.
which also gives the same result.
The backslash is already interpreted by the java.util.Properties class.
To bypass this, you can extend it and tweak the load(InputStream) method as shown in this answer:
public class PropertiesEx extends Properties {
public void load(FileInputStream fis) throws IOException {
Scanner in = new Scanner(fis);
ByteArrayOutputStream out = new ByteArrayOutputStream();
while(in.hasNext()) {
out.write(in.nextLine().replace("\\","\\\\").getBytes());
out.write("\n".getBytes());
}
InputStream is = new ByteArrayInputStream(out.toByteArray());
super.load(is);
}
}
Use double backslash \\ to escape a backslash in java.
Related
So in the URL string at the beginning, in each of those URL, there are many lines of text displayed on each website. I need to find a way to determine which lines of text have the timezone and datetime values that I need. The TIMEZONELBL and DATETIMELBL constants are supposed to help me pass these lines. However, I am stuck on this. The code is in Java. I am somewhat new to code so bare with me!
public class Main {
private static final String[] urlList = {
"http://worldtimeapi.org/api/timezone/Europe/London.txt",
"http://worldtimeapi.org/api/timezone/America/New_York.txt",
"http://worldtimeapi.org/api/timezone/America/Chicago.txt",
"http://worldtimeapi.org/api/timezone/America/Los_Angeles.txt",
"http://worldtimeapi.org/api/timezone/Asia/Tokyo.txt",
"http://worldtimeapi.org/api/timezone/Australia/Sydney.txt"
};
public static void main(String[] args) {
System.out.println("=== Current Date/Times Around the World ===");
try {
for (String url : urlList) {
System.out.println(extractCurrentTimeInfo(url));
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
public static String extractCurrentTimeInfo(String urlstr) throws IOException {
final String TIMEZONELBL = "timezone: ";
final String DATETIMELBL = "datetime: ";
String timezone = null;
String datetime = null;
String result = "error";
URL url = new URL(urlstr);
URLConnection connection = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
// TODO - add code here
return result;
}
Assuming everything else works (Reading the content of the URL)
You can read the text line by line and use startsWith method to see if any of the string matches TIMEZONELBL or DATETIMELBL
Also looks like your method returns only one string. But you are looking for timezone and datetime. You might want to change the method signature to return a Object or a array that holds 2 values.
I am a begginer(recently began learning) at programming in Java and I need help.
I have to read from a file, which contains numbers. I would like to make a method for reading from a file. Then I need to analyze this data and write it in another file.
What I strugle with is if I make a method just to read from a file or do I also have to save this read data into a variable. Where should this variable be declared inside a method (if is inside, how do I use it outside), if is outside how do I use it inside a method and also outside. Can anyone help me clarify this? What am I doing wrong?
My code of what I wrote until now. File from which I had to read has houndreds of numbers.
public class Test1 {
public static void main(String[] args) {
String nameFile = "numbers.txt";
File file = new File(nameFile);
String contentFile ="";
}
//Method for reading a .txt file
private static String readFromFile(String nameFile, String contentFile) {
String line = "";
try {
BufferedReader read = new BufferedReader(new FileReader(nameFile));
while((line = read.readLine()) != null) {
line = contentFIle;
}
read.close();
} catch (IOException e) {
System.out.println("There was an error reading from a file");
}
return line;
}
}
Theoretically speaking: mathematical functions get input variables, they preform some transformation on the variables and output the result of the transformation.
For example: f(x) = x - 1, g(x) = x * 2
You can chain functions in a way that one functions output will be the other function input: g(f(2)). In this case, the number 2 is used as an input for function f(x) and the output of f(x) is the input of g(x).
Functions and methods in programming can work in a similar way, but It may be more readable to save function output into meaningful variable names, and then to apply these variables to the next function.
Instead of doing: outputText(processText(readText(someFilename)))
You can write (pseudocode):
someFilename = 'foo'
text = readText(someFilename)
processed = processText(text)
outputText(processed)
In java and in your context this would look like the following:
public class Test1 {
public static void main(String[] args) {
String nameFile = "numbers.txt";
String contentFile = readFromFileByName(nameFile);
String altered = processText(contentFile);
saveToFile(altered, "processed.txt");
}
private static String readFromFileByName(String nameFile) {
String fullRead = "";
try {
File file = new File(nameFile);
BufferedReader read = new BufferedReader(new FileReader(file));
String line; // define line variable
while((line = read.readLine()) != null) {
fullRead += line; // pay attention for the altered code
}
read.close();
} catch (IOException e) {
System.out.println("There was an error reading from a file");
} finally {
return fullRead;
}
}
private static List<Integer> stringToIntList(String string) {
return Arrays
.stream(text.split(", "))
.map(Integer::parseInt)
.collect(Collectors.toList());
}
private static String processText(String text) {
String processed = text.replace('H', 'h'); // Some heavy processing :)
return processed;
}
private static void saveToFile(String text, String fileName) {
// save <text> to file with filename <filename>
}
}
1) Line is the variable that you have read to. So you shouldn't change its value.
line = contentFIle;
if you need only first line this method should look like:
private static String readFromFile(String nameFile) {
String line = "";
try {
BufferedReader read = new BufferedReader(new FileReader(nameFile));
line = read.readLine();
read.close();
} catch (IOException e) {
System.out.println("There was an error reading from a file");
}
return line;
}
if you need a list of this:
List<String> lines = Collections.emptyList();
try {
Files.readAllLines(Paths.get(fileName), StandardCharsets.UTF_8);
} catch (IOException e) {
// do something
e.printStackTrace();
}
return lines;
2) Also you don't call readFromFile function. So you need to change the main method:
public static void main(String[] args) {
String nameFile = "numbers.txt";
String contentFile = readFromFile(nameFile);
}
3)For your particular case, there's no sense to call readFromFile with String contentFile because you don't use this variable.
I have a small project.
The project imports the txt file to String (coding similar to CSV - contains semicolons = ";").
In the next steps, the String is changed to ArrayList.
Then, using Predicate, I remove elements that do not interest me.
At the end I replace ArrayList on TreeSet to remove duplicates.
Unfortunately, there is a problem here because the duplicates occur ...
I checked in Notepadd ++ changing the encoding on ANSI to check whether there are no unnecessary characters.
Unfortunately, everything looks good and duplicates are still there.
Uploaded input file - https://drive.google.com/open?id=1OqIKUTvMwK3FPzNvutLu-GYpvocUsSgu
Any idea?
public class OpenSCV {
private static final String SAMPLE_CSV_FILE_PATH = "/Downloads/all.txt";
public static void main(String[] args) throws IOException {
File file = new File(SAMPLE_CSV_FILE_PATH);
String str = FileUtils.readFileToString(file, "utf-8");
str = str.trim();
String str2 = str.replace("\n", ";").replace("\"", "" ).replace("\n\n",";").replace("\\*www.*\\","")
.replace("\u0000","").replace(",",";").replace(" ","").replaceAll(";{2,}",";");
List<String> lista1 = new ArrayList<>(Arrays.asList((str2.split(";"))));
Predicate<String> predicate = s -> !(s.contains("#"));
Set<String> removeDuplicates = new TreeSet<>(lista1);
removeDuplicates.removeIf(predicate);
String fileName2 = "/Downloads/allMails.txt";
try ( BufferedWriter bw =
new BufferedWriter (new FileWriter (fileName2)) )
{
for (String line : removeDuplicates) {
bw.write (line + "\n");
}
bw.close ();
} catch (IOException e) {
e.printStackTrace ();
}
}
}
before doing str.replace you can try str.trim to remove any spaces or unwanted and unseen characters.
str = str.trim()
So far, I have this project where I read in a properties file using PropertiesConfiguration (from Apache), edit the values I would like to edit, and then save change to the file. It keeps the comments and formatting and such, but one thing it does change is taking the multi-line values formatted like this:
key=value1,\
value2,\
value3
and turns it into the array style:
key=value1,value2,value3
I would like to be able to print those lines formatted as the were before.
I did this via this method:
PropertiesConfiguration config = new PropertiesConfiguration(configFile);
config.setProperty(key,value);
config.save();
I created a work around in case anyone else needs this functionality. Also, there is probably a better way to do this, but this solution currently works for me.
First, set your PropertiesConfiguration delimiter to the new line character like so:
PropertiesConfiguration config = new PropertiesConfiguration(configFile);
config.setListDelimiter('\n');
Then you will need to iterate through and update all properties (to set the format):
Iterator<String> keys = config.getKeys();
while (keys.hasNext()) {
String key = keys.next();
config.setProperty(key,setPropertyFormatter(key, config.getProperty(key))) ;
}
use this method to format your value list data (as shown above):
private List<String> setPropertyFormatter(String key, Object list) {
List<String> tempProperties = new ArrayList<>();
Iterator<?> propertyIterator = PropertyConverter.toIterator(list, '\n');;
String indent = new String(new char[key.length() + 1]).replace('\0', ' ');
Boolean firstIteration = true;
while (propertyIterator.hasNext()) {
String value = propertyIterator.next().toString();
Boolean lastIteration = !propertyIterator.hasNext();
if(firstIteration && lastIteration) {
tempProperties.add(value);
continue;
}
if(firstIteration) {
tempProperties.add(value + ",\\");
firstIteration = false;
continue;
}
if (lastIteration) {
tempProperties.add(indent + value);
continue;
}
tempProperties.add(indent + value + ",\\");
}
return tempProperties;
}
Then it is going to be almost correct, except the save function takes the double backslash that is stored in the List, and turns it into 4 back slashes in the file! So you need to replace those with a single backslash. I did this like so:
try {
config.save(new File(filePath));
byte[] readIn = Files.readAllBytes(Paths.get(filePath));
String replacer = new String(readIn, StandardCharsets.UTF_8).replace("\\\\\\\\", "\\");
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath, false), "UTF-8"));
bw.write(replacer);
bw.close();
} catch (ConfigurationException | IOException e) {
e.printStackTrace();
}
With commons-configuration2, you would handle such cases with a custom PropertiesWriter implementation, as described in its documentation under "Custom properties readers and writers" (Reader biased though).
A writer provides a way to govern writing of each character that is to be written to the properties file, so you can achieve pretty much anything you desire with it (via PropertiesWriter.write(String)). There is also a convenient method that writes proper newlines (PropertiesWriter.writeln(String)).
For example, I had to handle classpath entries in a Netbeans Ant project project.properties file:
public class ClasspathPropertiesWriter extends PropertiesConfiguration.PropertiesWriter {
public ClasspathPropertiesWriter(Writer writer, ListDelimiterHandler delimiter) {
super(writer, delimiter);
}
#Override
public void writeProperty(String key, Object value, boolean forceSingleLine) throws IOException {
switch (key) {
case "javac.classpath":
case "run.classpath":
case "javac.test.classpath":
case "run.test.classpath":
String str = (String) value;
String[] split = str.split(":");
if (split.length > 1) {
write(key);
write("=\\");
writeln(null);
for (int i = 0; i < split.length; i++) {
write(" ");
write(split[i]);
if (i != split.length - 1) {
write(":\\");
}
writeln(null);
}
} else {
super.writeProperty(key, value, forceSingleLine);
}
break;
default:
super.writeProperty(key, value, forceSingleLine);
break;
}
}
}
public class CustomIOFactory extends PropertiesConfiguration.DefaultIOFactory {
#Override
public PropertiesConfiguration.PropertiesWriter createPropertiesWriter(
Writer out, ListDelimiterHandler handler) {
return new ClasspathPropertiesWriter(out, handler);
}
}
Parameters params = new Parameters();
FileBasedConfigurationBuilder<Configuration> builder =
new FileBasedConfigurationBuilder<Configuration>(PropertiesConfiguration.class)
.configure(params.properties()
.setFileName("project.properties")
.setIOFactory(new CustomIOFactory());
Configuration config = builder.getConfiguration();
builder.save();
I have a string consisting of file separators; e.g. "Bancs\Bancs_CP_P&MB.xml".
I want to separate the string based on "\".
Here's what I'm trying:
public class Stringoperations {
public static void main(String[] args) {
try {
String fileSeparator = System.getProperty("file.separator");
String TestCaseName = "Bancs" + fileSeparator + "Bancs_CP_P&MB.xml";
String[] tukde = TestCaseName.split("\\");
System.out.println(tukde[0]);
System.out.println(tukde[1]);
} catch (Exception e) {
e.getMessage();
} finally {
System.out.println("here");
}
}
}
But this is not working.
First: add a e.printStackTrace(); or something similar to your catch block, so you'll see what's actually wrong:
java.util.regex.PatternSyntaxException: Unexpected internal error near index 1
\
^
at java.util.regex.Pattern.error(Pattern.java:1924)
A back slash in Java string literals allows you place special chars into a string:
String withTab = "a\tb";
would print as "a b". To get a backslash in a Java string you need to escape it:
String withBackslash = "a\\b";
So this is what you done in the split invocation: you passed one java string back slash. Since String.split() evaluates the passed string a regular expression (Java Doc for String.split()), the back slash is treated as a RegEx. Backslash has a special meaning in regular expressions and cannot appear alone (Java Doc for Pattern). If you want a literal back slash you need to escape the back slash again:
String[] tukde = TestCaseName.split("\\\\");
First, putting that code into IntelliJ IDEA causes it to fuss at me with an illegal escape sequence. You have to escape the escape, so you'd be using \\\\ as valid backslash escape syntax.
Second, you should be splitting on fileSeparator, not an arbitrary backslash. The backslash actually varies from system to system (e.g. I'm on Linux Mint, and my separators are all forward slashes).
String[] tukde = TestCaseName.split(fileSeparator);
As a further note, there's no exceptions here that could be thrown (save for runtime), and blindly catching all exceptions isn't a good practice.
Try this code :-
public static void main(String[] args) {
try
{
String fileSeparator = System.getProperty("file.separator");
String TestCaseName = "Bancs"+fileSeparator+"Bancs_CP_P&MB.xml";
String[] tukde = TestCaseName.split("\\\\");
System.out.println(tukde[0]);
System.out.println(tukde[1]);
}catch(Exception e)
{
e.getMessage();
}
finally
{
System.out.println("here");
}
}
Out put :-
Bancs
Bancs_CP_P&MB.xml
here
What platform or OS are you working on. Maybe your default file separator is not "\". Try this :
public class Stringoperations {
public static void main(String[] args) {
try {
String fileSeparator = System.getProperty("file.separator");
String TestCaseName = "Bancs" + fileSeparator + "Bancs_CP_P&MB.xml";
String[] tukde = TestCaseName.split(fileSeparator); //This uses the default separator returned by System.getProperty
System.out.println(tukde[0]);
System.out.println(tukde[1]);
} catch (Exception e) {
e.getMessage();
} finally {
System.out.println("here");
}
}
}
EDIT :
Also as Makoto points out if you are bent on using "\" to split you need to use "\\" and not "\"
Try this:
String pattern = Pattern.quote(System.getProperty("file.separator"));
String[] splittedFileName = fileName.split(pattern);
public class Stringoperations {
public static void main(String[] args) {
try {
String fileSeparator = System.getProperty("file.separator");
String TestCaseName = "Bancs" + fileSeparator + "Bancs_CP_P&MB.xml";
String[] tukde = TestCaseName.split("\\\\");
System.out.println(tukde[0]);
System.out.println(tukde[1]);
} catch (Exception e) {
e.getMessage();
} finally {
System.out.println("here");
}
}
}
try this