Read file, replace string and create a new one with all content - java

I am trying to replace ? with - in my text document but just the ArrayList<String> is being written in the new file without all lines of the old one. How can I fix that?
File file = new File("D:\\hl_sv\\L09MF.txt");
ArrayList<String> lns = new ArrayList<String>();
Scanner scanner;
try {
scanner = new Scanner(file);
int lineNum = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
lineNum++;
if (line.contains("?")) {
line = line.replace("?", "-");
lns.add(line);
// System.out.println("I found it on line " + lineNum);
}
}
lines.clear();
lines = lns;
System.out.println("Test: " + lines);
FileWriter writer;
try {
writer = new FileWriter("D:\\hl_sv\\L09MF2.txt");
for (String str : lines) {
writer.write(str);
}
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

I don't understand why you're storing the lines in a List to begin with. I would perform the transform and print while I read. You don't need to test for the presence of the ? (replace won't alter anything if it isn't present). And, I would also use a try-with-resources. Something like
File file = new File("D:\\hl_sv\\L09MF.txt");
try (PrintWriter writer = new PrintWriter("D:\\hl_sv\\L09MF2.txt");
Scanner scanner = new Scanner(file)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
writer.println(line.replace('?', '-'));
}
} catch (Exception e) {
e.printStackTrace();
}

Examine this code:
if (line.contains("?")) {
line = line.replace("?", "-");
lns.add(line);
}
You are only adding the current line (with the replacement) if it had a ? in it, ignoring other lines. Restructure it to always add the existing line.
if (line.contains("?")) {
line = line.replace("?", "-");
}
lns.add(line);
Additionally, the part
if (line.contains("?"))
scans line to look for a ?, and then the code
line.replace("?", "-");
does the same thing, but this time also replacing any ? with -. You may as well scan line just once:
lns.add(line.replace("?", "-"));
Note that creating an ArrayList just to hold the new lines wastes a fair amount of memory if the file is large. A better pattern would be to write each line, modified if necessary, right after you read in the corresponding line.

Within your while loop you have an if statement checking the line which adds the altered line to the array. You also need to add the unaltered lines to the array.

This should fix your issue:
int lineNum = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
lineNum++;
if (line.contains("?")) {
line = line.replace("?", "-");
lns.add(line);
// System.out.println("I found it on line " + lineNum);
}
else{
lns.add(line);
}
Previously, you were only adding the line to your ArrayList if it contained a "?" character. You need to add the line to the ArrayList whether or not it contains "?"

I would use a different approach if I'm trying to work on the functionality you want to implement, please check this approach and tell me if this helps you :)
public void saveReplacedFile() {
//1. Given a file in your system
File file = new File("D:\\hl_sv\\L09MF.txt");
try {
//2. I will read it, not necessarily with Scanner, but use a BufferedReader instead
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
//3. Define a variable that will hold the value of each line
String line = null;
//and also the information of your file
StringBuilder contentHolder = new StringBuilder();
//why not get your line separator based on your O.S?
String lineSeparator = System.getProperty("line.separator");
//4. Check your file line by line
while ((line = bufferedReader.readLine()) != null) {
contentHolder.append(line);
contentHolder.append(lineSeparator);
}
//5. By this point, your contentHolder will contain all the data of your text
//But it is still a StringBuilder type object, why not convert it to a String?
String contentAsString = contentHolder.toString();
//6. Now we can replace your "?" with "-"
String replacedString = contentAsString.replace("?", "-");
//7. Now, let's save it in a new file using BufferedWriter :)
File fileToBeSaved = new File("D:\\hl_sv\\L09MF2.txt");
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(fileToBeSaved));
bufferedWriter.write(replacedString);
//Done :)
} catch (FileNotFoundException e) {
// Exception thrown if the file does not exist in your system
e.printStackTrace();
} catch (IOException e) {
// Exception thrown due to an issue with IO
e.printStackTrace();
}
}
Hope this is helpful. Happy coding :)

If you can use Java 8 then your code can be simplified to
try (PrintStream ps = new PrintStream("D:\\hl_sv\\L09MF2.txt");
Stream<String> stream = Files.lines(Paths.get("D:\\hl_sv\\L09MF.txt"))) {
stream.map(line -> line.replace('?', '-')).forEach(ps::println);
} catch (IOException e) {
e.printStackTrace();
}

Related

BufferedReader do not read the entire text file

I read about someone having troubles with BufferedReader: the reader simply do not read the first lines. I have instead the opposite problem. For example, in a text file with 300 lines, it arrives at 200, read it half of it and then the following string is given null, so it stops.
private void readerMethod(File fileList) throws IOException {
BigInteger steps = BigInteger.ZERO;
BufferedReader br = new BufferedReader(new FileReader(fileList));
String st;
//reading file line by line
try{
while (true){
st = br.readLine();
if(st == null){
System.out.println("Null string at line " + steps);
break;
}
System.out.println(steps + " - " + st);
steps = steps.add(BigInteger.ONE);
}
}catch(Exception e){
e.printStackTrace();
}
finally{
try{
br.close();
}catch(Exception e){}
}
}
The output of the previous slice of code is as expected until it reaches line 199 (starting from 0). Consider a file with 300 lines.
...
198 - 3B02D5D572B66A82F9D21EE809320DB3E250C6C9
199 - 6E2C69795CB712C27C4097119CE2C5765
Null string at line 200
Notice that, all lines have the same length, so in this output line 199 is not even complete. I checked the file text, and it's correct: it contains all 300 lines and they are all of the same length. Also, in the text there are only capitals letters and numbers, as you can see.
My question is: how can i fix this? I need that the BufferedReader read all the text, not just a part of it.
As someone asked i add here the remaining part of the code. Please notice that all capital names are constant of various type (int, string etc).
This is the method that is called by the main thread:
public void init(){
BufferedWriter bw = null;
List<String> allLines = createRandomStringLines(LINES);
try{
String fileName = "SHA1_encode_text.txt";
File logFile = new File(fileName);
System.out.println(logFile.getCanonicalPath());
bw = new BufferedWriter(new FileWriter(logFile));
for(int i = 0; i < allLines.size(); i++){
//write file
String o = sha1FromString(allLines.get(i));
//sha1FromString is a method that change the aspect of the string,
//replacing char by char. Is not important at the moment.
bw.write(o + "\n");
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
bw.close();
}catch(Exception e){}
}
}
The method that create the list of random string is the following. "SYMBOLS" is just a String contains all avaiable chars.
private List<String> createRandomStringLines(int i) {
List<String> list = new ArrayList<String>();
while(i!=0){
StringBuilder builder = new StringBuilder();
int count = 64;
while (count-- != 0) {
int character = (int)(Math.random()*SYMBOLS.length());
builder.append(SYMBOLS.charAt(character));
}
String generatedString = builder.toString();
list.add(generatedString);
i--;
}
return list;
}
Note that, the file written is totally correct.
Okay, thanks to the user ygor, i manage to resolve it. The problem was that the BufferReader stars his job when the BufferWriter isn't closed yet. It was sufficient to move the command line that require the reader to work, after the bufferWriter.close() command.

Line when reading a file is empty but the line is not null

I have a problem in java and i dont understand why, since i think i am doing text-book stuff.
An overview in what of want to do is:
I want to create a file that contains in each line two strings: documentPath, documentID (in this format: "documentPath;documentID;")
I want to be able to add lines at the end of the file and load the file to a Java Data Structure, lets say a HashSet.
Each time i want to add a new line, i load all the file in a HashSet, check if the line i want to add is not already there and eventually add it at the end. (small number of data - don't care about efficiency)
The code
Add file:
public void addFile(String documentPath) {
this.loadCollection(); //METHOD IS NOT CONTINUING: ERROR HERE
if (!documentsInfo.contains(documentPath)) {
try {
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(this.collectionFile, true)));
DocumentInfo documentInfo = new DocumentInfo(documentPath, ++this.IDcounter);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Load file:
public void loadCollection() {
if (loaded) {return;}
BufferedReader br;
try {
br = new BufferedReader(new FileReader(collectionFile));
String line;
while ( (line = br.readLine())!= null ) { //PROBLEM HERE
System.out.println("the line readed from file-" + line + "-");
System.out.println("is the line null: "+ (line==null));
System.out.println("line length: " + line.length());
DocumentInfo documentInfo = new DocumentInfo(line);
documentsInfo.add(documentInfo);
}
br.close();
open = true;
} catch (IOException e) {
e.printStackTrace();
}
}
create the line to add:
public DocumentInfo(String fileLine) {
String delimiter = Repository.DOCUMENT_FILE_SEPARATOR;
StringTokenizer tok = new StringTokenizer(fileLine, delimiter);
System.out.println("Tokenizer starts with string: " + fileLine);
this.documentPath = tok.nextToken(); //EXCEPTION here
this.documentId = Integer.parseInt(tok.nextToken());
}
public String toString() {
String sep = Repository.DOCUMENT_FILE_SEPARATOR;
return this.getDocumentPath()+sep+this.getDocumentId()+sep+"\n";
}
I am getting the exception at the Tokenizer method (java.util.NoSuchElementException) when i try to get the nextToken, but the problem comes from the loadCollection() method. The first time i read the contents of the file nothing is there, the line is empty (lenght: 0) but the line is not null, so the while-condition fails to stop the while iteration.
Here is what i get from the debbuging prints:
the line readed from file--
is the line null: false
line length: 0
Tokenizer starts with string:
Can anyone help me with this?
You get a null only when you have exhausted the stream. But the first line of the stream (your file) is just an empty line - and you load it, the result of the empty line, is an empty string (""). It can be easily solved by skipping lines with string.length() == 0, by adding the following in your while loop:
if (line.length() == 0) continue;
You might want to consider using trim() before checking the length as well, to avoid nasty spaces making the string.length() > 0

Android, splitting a .csv by line break?

Firstly, I'm crap at english. I hope it's okay;
I have a small project to do: parsing a .csv file:
Typical .csv file
The recording starts at 2014,Sep,9,4:40:24 PM
accX,accY,accZ,gX,gY,gZ,
-0.3958511,0.014643669,10.037987,-13.17548,-2.3169785,-3.2103431,
-0.29875562,0.014643669,10.037987,-53.558975,0.22515106,-36.11273,
-0.29875562,0.014643669,10.23412,-50.653694,0.7335739,-32.481117,
The recording ends at 2014,Sep,9,4:40:29 PM
 
I tried OPENcsv library but I couldn't make it work. So I find an explaination on stackOverFlow, and I used it, it works well. Initially, it split the file with commas "," and it works.
But I changed it to split it by line break, as you can see with line.split("\r?\n"). It doesn't work, it crash in fact.
MainActivity.java
File f = new File(path + "/" + "motionTracker/");
File f2 = new File(f + "/" + stringx);
try {
fis = new FileInputStream(f2.toString());
} catch (FileNotFoundException e1) {
// handle exception
}
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
String date = "kek";
String value = "wow";
String line = "lel";
try {
while ((line = reader.readLine()) != null) {
String[] RowData = line.split("\\r?\\n");
date = RowData[0];
value = RowData[1];
}
}
catch (IOException ex) {
// handle exception
}
finally {
try {
fis.close();
}
catch (IOException e) {
// handle exception
}
}
Do you think the problem is because there are no line break in a .csv file?
Or maybe I did something wrong with my code.
Thanks.
when you use a
BufferedReader reader
and read your file line by line
line = reader.readLine()
then your line doesn't contain a line break ('\n' or '\r?\n')...
so what will happen?
String[] RowData = line.split("\\r?\\n");
the size of this array MUST ALWAYS be 1 and would be the same as the String line
so ultimately
date = RowData[0]; // equal to line
value = RowData[1]; //index out of bounds - line has never been splitted
an IndexOutOfBounds-Exception will be thrown here...

remove '#' symbol from the beginning of the string in java

Sample data in csv file
##Troubleshooting DHCP Configuration
#Module 3: Point-to-Point Protocol (PPP)
##Configuring HDLC Encapsulation
Hardware is HD64570
So i want to get the lines as
#Troubleshooting DHCP Configuratin
Module 3: Point-to-Point Protocol(PPP)
#Configuring HDLC Encapsulation
Hardware is HD64570
I have written sample code
public class ReadCSV {
public static BufferedReader br = null;
public static void main(String[] args) {
ReadCSV obj = new ReadCSV();
obj.run();
}
public void run() {
String sCurrentLine;
try {
br = new BufferedReader(new FileReader("D:\\compare\\Genre_Subgenre.csv"));
try {
while ((sCurrentLine = br.readLine()) != null) {
if(sCurrentLine.charAt(0) == '#'){
System.out.println(sCurrentLine);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I am getting below error
##Troubleshooting DHCP Configuration
#Module 3: Point-to-Point Protocol (PPP)
##Configuring HDLC Encapsulation
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(Unknown Source)
at example.ReadCSV.main(ReadCSV.java:19)
Please suggest me how to do this?
Steps:
Read the CSV file line by line
Use line.replaceFirst("#", "") to remove the first # from each line
Write the modified lines to an output stream (file or String) which suites you
If the variable s contains the content of the CSV file as String
s = s.replace("##", "#");
will replace all the occurrencies of '##" with '#'
You need something like String line=buffer.readLine()
Check the first character of the line with line.charAt(0)=='#'
Get the new String with String newLine=line.substring(1)
This is a rather trivial question. Rather than do the work for you, I'll outline the steps that you need to take without gifting you the answer.
Read in a file line by line
Take the first line and check if the first character of this line is a # - If it is, create a substring of this line excluding the first character ( or use fileLine.replaceFirst("#", ""); )
Store this line somewhere in an array like data structure or simply replace the current variable with the edited one ( fileLine = fileLine.replaceFirst("#", ""); )
Repeat until no more lines left from file.
If you want to add these changes to the file, simply overwrite the old file with the new lines (e.g. Using a steam reader and setting second parameter to false would overwrite)
Make an attempt and show us what you have tried, people will be more likely to help if they believe you have attempted the problem yourself thoroughly first.
package stackoverflow.q_25054783;
import java.util.Arrays;
public class RemoveHash {
public static void main(String[] args) {
String [] strArray = new String [3];
strArray[0] = "##Troubleshooting DHCP Configuration";
strArray[1] = "#Module 3: Point-to-Point Protocol (PPP)";
strArray[2] = "##Configuring HDLC Encapsulation";
System.out.println("Original array: " + Arrays.toString(strArray));
for (int i = 0; i < strArray.length; i++) {
strArray[i] = strArray[i].replaceFirst("#", "");
}
System.out.println("Updated array: " + Arrays.toString(strArray));
}
}
//Output:
//Original array: [##Troubleshooting DHCP Configuration, #Module 3: Point-to-Point Protocol (PPP), ##Configuring HDLC Encapsulation]
//Updated array: [#Troubleshooting DHCP Configuration, Module 3: Point-to-Point Protocol (PPP), #Configuring HDLC Encapsulation]
OpenCSV reads CSV file line by line and gives you an array of strings, where each string is one comma separated value, right? Thus, you are operating on a string.
You want to remove '#' symbol from the beginning of the string (if it is there). Correct?
Then this should do it:
CSVReader reader = new CSVReader(new FileReader("yourfile.csv"));
String [] nextLine;
while ((nextLine = reader.readNext()) != null) {
if (nextLine[0].charAt(0) == '#') {
nextLine[0] = nextLine[0].substring(1, nextLine[0].length());
}
}
Replacing the first '#' symbol on each of the lines in the CSV file.
private List<String> getFileContentWithoutFirstChar(File f){
try (BufferedReader input = new BufferedReader(new InputStreamReader(new FileInputStream(f), Charset.forName("UTF-8")))){
List<String> lines = new ArrayList<String>();
for(String line = input.readLine(); line != null; line = input.readLine()) {
lines.add(line.substring(1));
}
return lines
} catch(IOException e) {
e.printStackTrace();
System.exit(1);
return null;
}
}
private void writeFile(List<String> lines, File f){
try(BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), StandardCharsets.UTF_8))){
for(String line : lines){
bw.write(content);
}
bw.flush();
}catch (Exception e) {
e.printStackTrace();
}
}
main(){
File f = new File("file/path");
List<Stirng> lines = getFileContent(f);
f.delete();
writeFile(lines, f);
}

Read next word in java

I have a text file that has following content:
ac und
accipio annehmen
ad zu
adeo hinzugehen
...
I read the text file and iterate through the lines:
Scanner sc = new Scanner(new File("translate.txt"));
while(sc.hasNext()){
String line = sc.nextLine();
}
Each line has two words. Is there any method in java to get the next word or do I have to split the line string to get the words?
You do not necessarily have to split the line because java.util.Scanner's default delimiter is whitespace.
You can just create a new Scanner object within your while statement.
Scanner sc2 = null;
try {
sc2 = new Scanner(new File("translate.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (sc2.hasNextLine()) {
Scanner s2 = new Scanner(sc2.nextLine());
while (s2.hasNext()) {
String s = s2.next();
System.out.println(s);
}
}
You already get the next line in this line of your code:
String line = sc.nextLine();
To get the words of a line, I would recommend to use:
String[] words = line.split(" ");
Using Scanners, you will end up spawning a lot of objects for every line. You will generate a decent amount of garbage for the GC with large files. Also, it is nearly three times slower than using split().
On the other hand, If you split by space (line.split(" ")), the code will fail if you try to read a file with a different whitespace delimiter. If split() expects you to write a regular expression, and it does matching anyway, use split("\\s") instead, that matches a "bit" more whitespace than just a space character.
P.S.: Sorry, I don't have right to comment on already given answers.
you're better off reading a line and then doing a split.
File file = new File("path/to/file");
String words[]; // I miss C
String line;
HashMap<String, String> hm = new HashMap<>();
try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")))
{
while((line = br.readLine() != null)){
words = line.split("\\s");
if (hm.containsKey(words[0])){
System.out.println("Found duplicate ... handle logic");
}
hm.put(words[0],words[1]); //if index==0 is ur key
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
You can just use Scanner to read word by word, Scanner.next() reads the next word
try {
Scanner s = new Scanner(new File(filename));
while (s.hasNext()) {
System.out.println("word:" + s.next());
}
} catch (IOException e) {
System.out.println("Error accessing input file!");
}

Categories

Resources