I'm just wondering if there's a way to read a text file and skip a line with specific string.
For example (test1.txt):
test0,orig,valid,nice
test1,input,of,ol,[www]
test2,[eee],oa,oq
test3,wa,eee,string,int
test4,asfd,eee,[tsddas],wwww
Expected output :
test0,orig,valid,nice
test3,wa,eee,string,int
I already have this code :
String line;
String test[];
try{
LineIterator it = FileUtils.lineIterator(file2,"UTF-8");
while(it.hasNext()){
line = it.nextLine();
test = StringUtils.split(line,(","));
}
Thanks in advance guys!
Something like:
line = it.nextLine();
if (line.contains("specific string")) continue;
test = StringUtils.split(line,(","));
Why are you using StringUtils to split a line? The String class supports a split(...) method.
I suggest you read the String API for basic functionality.
You could also make use of the Java 8 Streaming API. It allows all this rather easily.
final List<String[]> rows = Files.lines(Paths.get(file2), "UTF-8")
.filter(l -> !l.contains("["))
.map(l -> l.split(","))
.collect(Collectors.toList());
If you want to do it fast and don't want to run into any issues, you should also think about using an existing CSV library. A nice example is the Apache Commons CSV library (https://commons.apache.org/proper/commons-csv/).
Related
I am writing a small java method that needs to read test data from a file on my win10 laptop.
The test data has not been formed yet but it will be text based.
I need to write a method that reads the data and analyses it character by character.
My questions are:
what is the simplest format to create and read the file....I was looking at JSON, something that does not look particularly complex but is it the best for a very simple application?
My second question (and I am a novice). If the file is in a text file on my laptop.....how do I tell my java code where to find it....how do I ask java to navigate the win10 operating system?
You can also map the text file into java objects (It depends on your text file).
For example, we have a text file that contains person name and family line by line like:
Foo,bar
John,doe
So for parse above text file and map it into a java object we can :
1- Create a Person Object
2- Read and parse the file (line by line)
Create Person Class
public class Person {
private String name;
private String family;
//setters and getters
}
Read The File and Parse line by line
public static void main(String[] args) throws IOException {
//Read file
//Parse line by line
//Map into person object
List<Person> personList = Files
.lines(Paths
.get("D:\\Project\\Code\\src\\main\\resources\\person.txt"))
.map(line -> {
//Get lines of test and split by ","
//It split words of the line and push them into an array of string. Like "John,Doe" -> [John,Doe]
List<String> nameAndFamily = Splitter.on(",").trimResults().omitEmptyStrings().splitToList(line);
//Create a new Person and get above words
Person person = new Person();
person.setName(nameAndFamily.get(0));
person.setFamily(nameAndFamily.get(1));
return person;
}
).collect(Collectors.toList());
//Process the person list
personList.forEach(person -> {
//You can whatever you want to the each person
//Print
System.out.println(person.getName());
System.out.println(person.getFamily());
});
}
Regarding your first question, I can't say much, without knowing anything about the data you like to write/read.
For your second question, you would normally do something like this:
String pathToFile = "C:/Users/SomeUser/Documents/testdata.txt";
InputStream in = new FileInputStream(pathToFile);
As your data gains more complexity you should probably think about using a defined format, if that is possible, something like JSON, YAML or similar for example.
Hope this helps a bit. Good luck with your project.
As for the format the text file needs to take, you should elaborate a bit on the kind of data. So I can't say much there.
But to navigate the file system, you just need to write the path a bit different:
The drive letter is a single character at the beginning of the path i.e. no colon ":"
replace the backslash with a slash
then you should be set.
So for example...
C:\users\johndoe\documents\projectfiles\mydatafile.txt
becomes
c/users/johndoe/documents/projectfiles/mydatafile.txt
With this path, you can use all the IO classes for file manipulation.
I used InputStream, and on parsing, if there is a "," in one column then it considers it as a separate column.
ex - abc, xyz, "m,n"
then the parsed output is abc , xyz, m, n
Here m and n are considered as separate columns.
There are many thirdParty Csv parsing library like
UniVocity Parser
CommonsCsv Parser
OpenCsv Parser
SuperCsv Parser
I am using UniVocity csv parser which is very fast and automatically detect separator in rows. You can go through above given csv libraries.
I really like the Apache Commons CSVParser. This is almost verbatim from their user guide:
Reader reader = new FileReader("input.csv");
final CSVParser parser = new CSVParser(reader, CSVFormat.DEFAULT);
try {
for (final CSVRecord record : parser) {
final String string = record.get("SomeColumn");
...
}
} finally {
parser.close();
reader.close();
}
This is simple, configurable and line-oriented.
You could configure it like this:
final CSVParser parser = new CSVParser(reader, CSVFormat.DEFAULT.withHeader().withDelimiter(';'));
For the record, this configuration is unnecessary, as the CSVFormat.DEFAULT works exactly the way you want it to.
This would be my first attempt to see whether it fits into the memory. If it doesn't, can you be a little more specific about low memory footprint?
This question already has an answer here:
Java - Skip first line while using try with resources
(1 answer)
Closed 6 years ago.
I am trying to read a large file line by line, in java, using NIO library.
But this file also contains headers...
try (Stream<String> stream = Files.lines(Paths.get(schemaFileDir+File.separator+schemaFileNm))){
stream.forEach(s->sch.addRow(s.toString(),file_delim));
}
How do i modify this to skip the first line of the file?
Any pointers..?
Use the Stream.skip method to skip the header line.
try (Stream<String> stream = Files.lines(
Paths.get(
schemaFileDir+File.separator+schemaFileNm)).skip(1)){
// ----
}
Hope this helps!
You can opt to try using Iterator
Iterator<String> iter = Files.lines(Paths.get(schemaFileDir+File.separator+schemaFileNm)).iterator();
while (iter.hasNext()) {
iter.next(); // discard 1st line
sch.addRow(iter.next().toString(),file_delim); // process
}
The question is: why do you want to do that?
My guess is you're reading a CSV file. In that case you soon will run into other problems like how do I distinguish strings from numbers? or How do I handle double-quotes, semicolon or comma within ""?
My suggestion is to avoid all that trouble right from the start by using a CSV reader framework to parse the file.
I came across the following Java code snippet ( source ), that is used to read the last line in a file. It uses two Apache libraries - ReversedLinesFileReader and FileUtils. Here it is :
ReversedLinesFileReader reader = new ReversedLinesFileReader(FileUtils.getFile(file));
String s = "";
while ((s = reader.readLine()) != null) {
System.out.println(s);
}
What I don't understand however, is why do we not simply put in a file path for the argument to ReversedLinesFileReader , and instead we use the FileUtils class.
Why Can't I simply say instead:
File someFile = new File("someFile.txt");
ReversedLinesFileReader reader = new ReversedLinesFileReader( someFile ) ;
thanks
... what is the advantage of using the Apache FileUtils class?
If file is just one string, there is no advantage. The call to getFile is going to call new File(file) ... after messing around to cope with the "var-args-ness" of the file parameter. So in fact, there is a performance penalty for using getFile in this case, for zero concrete1 benefit.
If file is a String[], then FileUtils.getFile(file) turns the strings into a file path.
Why Can't I simply say instead ...
Assuming that file is a String, you can, and (IMO) you should do what you proposed.
1 - I have seen people argue in cases like this that it is an advantage to avoid using the java.io classes directly, but frankly I don't buy it.
Using File is fine. ReversedLinesFileReader has a constructor that accepts a File as an input.
The reason you would use FileUtils is if you could benefit from what the FileUtils.getFile() overloaded methods offer, like passing a String[] of path elements, etc.
Other than that, no difference.
I want to parse java code using java.
problem is , when I pass the java code to parse method,it does not take it as string.How do I escape the code to be parsed
public class JavaParser {
private int noOfLines;
public void parse(String javaCode){
String[] lines = javaCode.split("[\r\n]+");
for(String line : lines)
System.out.println(line);
}
public static void main(){
JavaParser a = new JavaParser();
a.parse("java code;");
}
}
You need to read the java code file as a text file, line by line or alla t once for example:
FileInputStream inputStream = new FileInputStream("foo.java");
try {
String everything = IOUtils.toString(inputStream);
} finally {
inputStream.close();
}
Then you can parse the everything string.
maybe you can describe what you're trying to achieve?
In general its java's compiler (like javac) work to parse the java source files.
Quick googling revealed this project that can suit your needs
As of java 6 you can invoke compiler as a part of your code (java exposes the compiler API). This can be helpful if you're trying to compile the code after you read it. In general you can read this article, maybe you'll find it helpful
Hope this helps