I have problem reading values like (\+?\s*[0-9]+\s*)+ from properties file in java, because the value , what I get with getProperty() method is (+?s*[0-9]+s*)+.
Escaping of values in properties file is not an option yet.
Any ideas?
I am pretty late to answer this question, but maybe this could help others that end up here.
Newer versions of Java (not sure which, I am using 8) support escaping of values by using \\ to represent the normal \ we are used to.
For example, in your case, (\\+?\\s*[0-9]+\\s*)+ is what you are looking for.
I think this class could be solution for the backslash problem in properties file.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
public class ProperProps {
HashMap<String, String> Values = new HashMap<String, String>();
public ProperProps() {
};
public ProperProps(String filePath) throws java.io.IOException {
load(filePath);
}
public void load(String filePath) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(filePath));
String line;
while ((line = reader.readLine()) != null) {
if (line.trim().length() == 0 || line.startsWith("#"))
continue;
String key = line.replaceFirst("([^=]+)=(.*)", "$1");
String val = line.replaceFirst("([^=]+)=(.*)", "$2");
Values.put(key, val);
}
reader.close();
}
public String getProperty(String key) {
return Values.get(key);
}
public void printAll() {
for (String key : Values.keySet())
System.out.println(key +"=" + Values.get(key));
}
public static void main(String [] aa) throws IOException {
// example & test
String ptp_fil_nam = "my.prop";
ProperProps pp = new ProperProps(ptp_fil_nam);
pp.printAll();
}
}
Just read using a classical BufferedReader instead:
final URL url = MyClass.class.getResource("/path/to/propertyfile");
// check if URL is null;
String line;
try (
final InputStream in = url.openStream();
final InputStreamReader r
= new InputStreamReader(in, StandardCharsets.UTF_8);
final BufferedReader reader = new BufferedReader(r);
) {
while ((line = reader.readLine()) != null)
// process line
}
Adapt to Java 6 if necessary...
Related
I have a file called "marathon", where I have 7 keys:
sex
time
athlete
athlete's nationality
date
city
country
splitted by a comma ",". I have to put the second key (time) in a Treemap.
At the moment I am just trying to show only the time in the console.
So here is my code:
public class Text {
#SuppressWarnings("resource")
public static void main(String[] args) throws FileNotFoundException {
try {
BufferedReader in = new BufferedReader(new FileReader("marathon"));
String str;
str = in.readLine();
while ((str = in.readLine()) != null) {
//System.out.println(str);
String[] ar=str.split(",");
System.out.println(ar[0]);
}
in.close();
} catch (IOException e) {
System.out.println("File Read Error");
}
}
}
This is what a line of the text looks like:
M, 2:30:57.6, Harry Payne, GBR, 1929-07-05, Stamford Bridge, England
When I start the program of my code example and put in System.out.println(ar[0]); a[0] shows me the first line in the console so M's and F's. But when I put a[1] there is an exception:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
As others have pointed out, you do readline twice before you get into the body of the loop, so you will miss the first line.
But you are also not checking that readline resulted in a properly formatted line. It may be an empty line or a line that in some other way does not result in an array that you expect.
So you should add an if-statement that checks that you have what you expected, like so...
public class Text {
#SuppressWarnings("resource")
public static void main(String[] args) throws FileNotFoundException {
try {
BufferedReader in = new BufferedReader(new FileReader("marathon"));
String str = "";
while ((str = in.readLine()) != null) {
String[] ar=str.split(",");
if(ar.length >= 7) {
System.out.println(ar[0] + ", " + ar[1]);
}
}
in.close();
} catch (IOException e) {
System.out.println("File Read Error");
}
}
}
Please try the code below. It's working for me.
You should have read the line only once in the while loop.
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Text {
#SuppressWarnings("resource")
public static void main(String[] args) throws FileNotFoundException {
try {
BufferedReader in = new BufferedReader(new FileReader("marathon"));
String str;
while ((str = in.readLine()) != null) {
//System.out.println(str);
String[] ar=str.split(",");
System.out.println(ar[0]);
System.out.println(ar[1]);
}
in.close();
} catch (IOException e) {
System.out.println("File Read Error");
}
}
}
SortedMap<String, String[]> map = new TreeMap<>();
Path path = Paths.get("marathon");
Files.lines(path, Charsets.defaultCharset())
.map(line -> line.split(",\\s*"))
.peek(words -> {
if (words.length != 7) {
Logger.getLogger(getClass().getName()).info("Line wrong: " + line);
}
})
.filter(words -> words.length == 7)
.forEach(words -> map.put(word[1], words));
However there are CSV reader classes out there, that can handle quoted fields with commas and such.
Java 8 just for fun
import java.io.IOException;
import java.nio.file.*;
import java.util.*;
import java.util.stream.Stream;
import static java.nio.charset.Charset.defaultCharset;
import static java.lang.System.out;
import static java.nio.file.Files.lines;
public class Main {
public static void main(String[] args) throws IOException {
Map<String, String[]> map = new TreeMap<>( );
try( Stream<String> lines = lines(Paths.get("marathon"), defaultCharset())){
lines.map(line -> line.split( "," )).forEach( entry -> map.put(entry[1], entry ));
map.values().forEach( entry -> out.println(Arrays.toString( entry )) );
}
}
}
I'm trying to read a file in java. In that file, some string is given which I want to print. But my code prints only lines of even numbers and skips lines of odd numbers.
I searched for that in stackoverflow, but have found no solution previously answered.
My code is given below...
//main class
import java.io.IOException;
public class takingInputFrpmFile {
public static void main(String[] args) throws IOException {
String filePath = "F:/Path/in.txt";
try
{
readFile rF = new readFile(filePath);
String[] receivedArray = rF.Read();
for(int i=0;i<receivedArray.length;i++)
System.out.println(receivedArray[i]);
}
catch(IOException e)
{
System.out.println(e.getMessage());
}
}
}
// class called from main class
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;
public class readFile {
private String path;
public readFile(String path)
{
this.path=path;
}
public String[] Read() throws IOException
{
FileReader fR = new FileReader(path);
BufferedReader bR = new BufferedReader(fR);
String[] textData = new String[110];
String check;
int i=0;
while((check = bR.readLine()) != null)
{
textData[i] = bR.readLine();
i++;
}
bR.close();
return textData;
}
}
The file contains this lines...
This is the output of my code....
What is wrong with my code? What should I change? How to get rid of printing that last nulls ? Help please... Thanks in advance...
You are first reading the line and checking it's not null, then you read another line.
while((check = bR.readLine()) != null)
{
textData[i] = check; //Changed this to check
i++;
}
That one will work.
You are currently declaring String array which has size of 110. Is your file really 110 line long? You probably should use list instead.
public List<String> Read() throws IOException
{
FileReader fR = new FileReader(path);
BufferedReader bR = new BufferedReader(fR);
List<String> textData = new ArrayList<>();
String check;
while((check = bR.readLine()) != null)
{
textData.add(check);
}
bR.close();
return textData;
}
If you really want to return string array you can use:
return textData.toArray(new String[textData.size()]);
You are reading file lines twice, one when you do
check = bR.readLine()
and other when you do
textData[i] = bR.readLine();
(Each bR.readLine() reads one line)
Try changing your loop for something like
while ((textData[i] = bR.readLine()) != null) {
i++;
}
To get rid of the nulls, you can use a List instead of using a fixed size (110) array.
I suggest the following code:
//main class
import java.io.IOException;
import java.util.List;
public class Prueba {
public static void main(String[] args) throws IOException {
String filePath = "E:/Temp/in.txt";
try {
ReadFile rF = new ReadFile(filePath);
List<String> receivedArray = rF.read();
for (String currentLine : receivedArray) {
System.out.println(currentLine);
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
//class called from main class
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class ReadFile {
private final String path;
public ReadFile(String path) {
this.path = path;
}
public List<String> read() throws IOException {
// Create an empty List to protect against NPE
List<String> textData = new ArrayList<String>();
FileReader fR = null;
BufferedReader bR = null;
try {
fR = new FileReader(path);
bR = new BufferedReader(fR);
String line;
while ((line = bR.readLine()) != null) {
textData.add(line);
}
} catch (IOException e) {
throw e;
} finally {
// Close all the open resources
bR.close();
fR.close();
}
return textData;
}
}
Anyway, as Mukit Chowdhury suggested, please respect code conventions to make your code more readable (you can Google "Java code conventions" or use a well stablished ones)
It seems you do 2 read statements. Try something like:
while((check = bR.readLine()) != null)
{
textData[i] = check;
i++;
}
your line pointer incrementing two times,
while((check = bR.readLine()) != null){
textData[i] = bR.readLine();
i++;
}
Replace bR.readLine() to check in your while loop.
while((check = bR.readLine()) != null){
textData[i] = check ;
i++;
}
You call readline twice. Your loop should read
for(; (check = br.readline()) != null; textdata[i++] = check);
Or something to that effect
In Java 8, reading all lines from a File into a List<String> is easily done using utility classes from the java.nio.file package:
try {
List<String> lines = Files.readAllLines(Paths.get("/path/to/file"));
} catch (IOException e) {
// handle error
}
It's really no longer necessary to use external libraries or to re-invent the wheel for such a common task :)
From your code sample
here
while((check = bR.readLine()) != null) {
textData[i] = bR.readLine();
i++;
}
replace it with
while((check = bR.readLine()) != null) {
textData[i] = check ;
i++;
}
I am trying to use following code to edit html page using java.
package com.XXX.xxx.xxx
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class HTMLReading {
/**
* #param args
*/
public static void main(String[] args) {
StringBuilder contentBuilder = new StringBuilder();
try {
BufferedReader in = new BufferedReader(new FileReader("C:\\ItemDetails.html"));
String str;
while ((str = in.readLine()) != null) {
if(str.equals("<div id=\"row2\" style=\"display:none;\" ><ul>")) {
// add following lines to html
//<li><b>Comments</b></li><ul><li>Testing for comment</li></ul>
}
System.out.println(str);
}
in.close();
} catch (IOException e) {
}
}
}
On reading perticular line, I want to insert some new line to html.
//<li><b>Comments</b></li><ul><li>Testing for comment</li></ul>
I tried Append, but it adds the line at end, not at the place where I want.
And my requirement is I have to use only JAVA only for this.
Any thoughts!
You can use Java.io.BufferedWriter.newLine() method.
It's non static method, you can find some documantation here:
http://www.tutorialspoint.com/java/io/bufferedwriter_newline.htm
Also,
You better use StringBuffer and not just String, because it's an immutable object like:
StringBuffer sb = new StringBuffer();
sb.append ("<br>blabla<br>");
You could try something like this:
String str;
StringBuilder contentBuilder = new StringBuilder();
while ((str = in.readLine()) != null) {
if(str.equals("<div id=\"row2\" style=\"display:none;\" ><ul>")) {
contentBuilder.append("add your content" + str);
}
else
{
contentBuilder.append(str);
}
System.out.println(str);
}
You can store it in a String then write combined to the file over what was there.
Newlines are represented in Java as "\n". It sounds like you want your StringBuilder to contain the contents of the original file, plus the additional lines you describe. To accomplish that your code might look like:
public static void main(String[] args) {
StringBuilder contentBuilder = new StringBuilder();
try (BufferedReader in = new BufferedReader(new FileReader("C:\\ItemDetails.html"))) {
String str;
while ((str = in.readLine()) != null) {
contentBuilder.append(str);
if (str.equals("<div id=\"row2\" style=\"display:none;\" ><ul>")) {
contentBuilder.append("\n<li><b>Comments</b></li><ul><li>Testing for comment</li></ul>\n);
}
}
} catch (IOException e) {
}
System.out.println(contentBuilder.toString());
}
my data in the text file looks like this...
3
movie title
4
movie title
1
movie title
the number on top is the movie rating and the text under it is the movie title.
The code I have so far is below. But It's not printing anything out except empty brackets! Sample code would be appreciated!
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class MovieReview {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<Integer, String>();
BufferedReader br = new BufferedReader(new FileReader("C:/Users/sgoetz/Desktop/movieReviews.txt"));
String line = br.readLine();
while (line != null) {
line = br.readLine();
System.out.println(map);
}
}
Try This
public static void main(String[] args) throws IOException {
Map<Integer, String> map = new HashMap<Integer, String>();
BufferedReader br = new BufferedReader(new FileReader("movieReviews.txt"));
String line="";
int i=0;
while (line != null) {
line = br.readLine();
map.put(i,line);
i++;
}
for(int j=0;j<map.size();j++){
System.out.println(map.get(j));
}
}
Your code is printing nothing because you are printing the map on which you put nothing. So the map remains empty. Also your first while iteration is buggy, you read one line from the stream before the while loop then you enter it an immediately read the next line. The first line is lost.
For reading from a buffered stream the following pattern should be considered:
while(null != (line = br.readLine())) {
// do what ever you want with the line.
}
If you want to store moving names of against its rating you have to declare map as Map>. Following code populates the movie title against its rating. Hope this is helpful.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
public class MovieReview {
public static void main(String[] args) {
Map<Integer, List<String>> map = new HashMap<Integer, List<String>>();
BufferedReader br = new BufferedReader(new FileReader("C:/Users/sgoetz/Desktop/movieReviews.txt"));
String line = null;
while ((line = br.readLine()) != null) {
//Rating
int rating = Integer.parseInt(line);
//Movie name
line = br.readLine();
List<String> movieList = map.get(rating);
if(movieList == null) {
movieList = new ArrayList<String>();
map.put(rating, movieList);
}
//Adding movie name to list
movieList.add(line);
}
}
}
}
here we go
File:
3,movie title,rating,other,other
4,movie title,rating,other,other
1,movie title,rating,other,other
code:
public static void main(String[] args) throws IOException {
Map<Integer, String> map = new HashMap<Integer, String>();
BufferedReader br = new BufferedReader(new FileReader("movieReviews.txt"));
String line="";
int i=0;
while (line != null) {
line = br.readLine();
map.put(i,line);
i++;
}
String movieNumber="";
String movieTitle="";
String movieRating="";
String movieOther1="";
String movieOther2="";
for(int j=0;j<map.size();j++){
if(!(map.get(j)== null)){
String[] getData=map.get(j).toString().split("\\,");
movieNumber = getData[0];
movieTitle = getData[1];
movieRating = getData[2];
movieOther1 = getData[3];
movieOther2 = getData[4];
System.out.println("|"+movieNumber+"|"+movieTitle+"|"+movieRating+"|"+movieOther1+"|"+movieOther2);
}
}
}
A more example:
while (true) {
// Number line
String value = br.readLine();
if (value == null || value.trim().isEmpty()) {
break;
}
Integer valueInt = Integer.parseInt(value);
// Name line
String title = br.readLine();
if (title == null || value.trim().isEmpty()) {
break;
}
map.put(valueInt, title);
}
System.out.println(map);
And the output is:
{1=movie title, 3=movie title, 4=movie title}
I was wondering if anyone has logic in java that removes duplicate lines while maintaining the lines order.
I would prefer no regex solution.
public class UniqueLineReader extends BufferedReader {
Set<String> lines = new HashSet<String>();
public UniqueLineReader(Reader arg0) {
super(arg0);
}
#Override
public String readLine() throws IOException {
String uniqueLine;
if (lines.add(uniqueLine = super.readLine()))
return uniqueLine;
return "";
}
//for testing..
public static void main(String args[]) {
try {
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream(
"test.txt");
UniqueLineReader br = new UniqueLineReader(new InputStreamReader(fstream));
String strLine;
// Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
if (strLine != "")
System.out.println(strLine);
}
// Close the input stream
in.close();
} catch (Exception e) {// Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
}
Modified Version:
public class UniqueLineReader extends BufferedReader {
Set<String> lines = new HashSet<String>();
public UniqueLineReader(Reader arg0) {
super(arg0);
}
#Override
public String readLine() throws IOException {
String uniqueLine;
while (lines.add(uniqueLine = super.readLine()) == false); //read until encountering a unique line
return uniqueLine;
}
public static void main(String args[]) {
try {
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream(
"/home/emil/Desktop/ff.txt");
UniqueLineReader br = new UniqueLineReader(new InputStreamReader(fstream));
String strLine;
// Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
System.out.println(strLine);
}
// Close the input stream
in.close();
} catch (Exception e) {// Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
}
If you feed the lines into a LinkedHashSet, it ignores the repeated ones, since it's a set, but preserves the order, since it's linked. If you just want to know whether you've seena given line before, feed them into a simple Set as you go on, and ignore those which the Set already contains/contained.
It can be easy to remove duplicate line from text or File using new java Stream API. Stream support different aggregate feature like sort,distinct and work with different java's existing data structures and their methods. Following example can use to remove duplicate or sort the content in File using Stream API
package removeword;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Scanner;
import java.util.stream.Stream;
import static java.nio.file.StandardOpenOption.*;
import static java.util.stream.Collectors.joining;
public class Java8UniqueWords {
public static void main(String[] args) throws IOException {
Path sourcePath = Paths.get("C:/Users/source.txt");
Path changedPath = Paths.get("C:/Users/removedDouplicate_file.txt");
try (final Stream<String> lines = Files.lines(sourcePath )
// .map(line -> line.toLowerCase()) /*optional to use existing string methods*/
.distinct()
// .sorted()) /*aggregrate function to sort disctincted line*/
{
final String uniqueWords = lines.collect(joining("\n"));
System.out.println("Final Output:" + uniqueWords);
Files.write(changedPath , uniqueWords.getBytes(),WRITE, TRUNCATE_EXISTING);
}
}
}
Read the text file using a BufferedReader and store it in a LinkedHashSet. Print it back out.
Here's an example:
public class DuplicateRemover {
public String stripDuplicates(String aHunk) {
StringBuilder result = new StringBuilder();
Set<String> uniqueLines = new LinkedHashSet<String>();
String[] chunks = aHunk.split("\n");
uniqueLines.addAll(Arrays.asList(chunks));
for (String chunk : uniqueLines) {
result.append(chunk).append("\n");
}
return result.toString();
}
}
Here's some unit tests to verify ( ignore my evil copy-paste ;) ):
import org.junit.Test;
import static org.junit.Assert.*;
public class DuplicateRemoverTest {
#Test
public void removesDuplicateLines() {
String input = "a\nb\nc\nb\nd\n";
String expected = "a\nb\nc\nd\n";
DuplicateRemover remover = new DuplicateRemover();
String actual = remover.stripDuplicates(input);
assertEquals(expected, actual);
}
#Test
public void removesDuplicateLinesUnalphabetized() {
String input = "z\nb\nc\nb\nz\n";
String expected = "z\nb\nc\n";
DuplicateRemover remover = new DuplicateRemover();
String actual = remover.stripDuplicates(input);
assertEquals(expected, actual);
}
}
Here's another solution. Let's just use UNIX!
cat MyFile.java | uniq > MyFile.java
Edit: Oh wait, I re-read the topic. Is this a legal solution since I managed to be language agnostic?
For better/optimum performance, it's wise to use Java 8's API features viz. Streams & Method references with LinkedHashSet for Collection as below:
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.LinkedHashSet;
import java.util.stream.Collectors;
public class UniqueOperation {
private static PrintWriter pw;
enter code here
public static void main(String[] args) throws IOException {
pw = new PrintWriter("abc.txt");
for(String p : Files.newBufferedReader(Paths.get("C:/Users/as00465129/Desktop/FrontEndUdemyLinks.txt")).
lines().
collect(Collectors.toCollection(LinkedHashSet::new)))
pw.println(p);
pw.flush();
pw.close();
System.out.println("File operation performed successfully");
}
here I'm using a hashset to store seen lines
Scanner scan;//input
Set<String> lines = new HashSet<String>();
StringBuilder strb = new StringBuilder();
while(scan.hasNextLine()){
String line = scan.nextLine();
if(lines.add(line)) strb.append(line);
}