I have the following code:
public static void main(String[] args) throws IOException {
//File being read:
String fileName = "src/data/Belgium.csv";
String[] nextLine;
try (CSVReader reader = new CSVReader(new FileReader(fileName), ',', '"', 1)) {
while ((nextLine = reader.readNext()) != null) {
for (String line : nextLine) {
//NewFile
//When 2nd parameter - ture, it gets so big, that excel can't handle it anymore...
FileWriter writer = new FileWriter("src/dataNew/BelgiumNew1.csv", true);
line = line.replaceAll("T", " ");
line = line.replaceAll("Z", "");
line = line.replaceAll("ActualGenerationPerUnit.mean", "");
line = line.replaceAll("Plantname:", "");
//Escaping curly braces is a must!
line = line.replaceAll("\\{", "");
line = line.replaceAll("\\}", "");
writer.append(line);
writer.flush();
writer.close();
System.out.println(line);
}
}System.out.println("Successfully written");
}
}
The output of the code in my console, using System.out.println(line) gives me the correct output.
However, when I open the CSV file, it seems like it is written reversed.
Excel first complains about the amount of rows.
However, only the last row of my original dataset shows.
The dataset (which is preprocessed in an inefficient way), contains more than 1000 rows. Therefore, I can not simply append every single entry.
Is there a better way of doing this?
Tips and tricks are very welcome.
Furtermore, I have tried several writers:
- CSVwrite
- BufferedWriter
- FileWriter
Also checked other issues on Stackoverflow...
Can't seem to make it work. Thank you!
UPDATE:
Question is answered! Final code:
public static void main(String[] args) throws IOException {
//File being read:
String fileName = "src/data/Belgium.csv";
//When 2nd parameter - ture, it gets so big, that excel can't handle it anymore...
FileWriter writer = new FileWriter("src/dataNew/BelgiumNew5.csv", true);
String[] nextLine;
try (CSVReader reader = new CSVReader(new FileReader(fileName), ',', '"', 1)) {
while ((nextLine = reader.readNext()) != null) {
for (String line : nextLine) {
line = line.replaceAll("T", " ");
line = line.replaceAll("Z", "");
line = line.replaceAll("ActualGenerationPerUnit.mean", "");
line = line.replaceAll("Plantname:", "");
//Escaping curly braces is a must!
line = line.replaceAll("\\{", "");
line = line.replaceAll("\\}", "");
writer.append(line);
writer.append(System.lineSeparator());
System.out.println(line);
}
}System.out.println("Successfully written");
}catch(Exception e){
e.printStackTrace();
}finally {
if (writer != null){
writer.flush();
writer.close();
}
}
}
However, when I open the CSV file, it seems like it is written
reversed. Excel first complains about the amount of rows. However,
only the last row of my original dataset shows.
I think that it is probably caused because a new line character between CSV rows is missing.
Actually you don't write a new line character when you write a row in the file.
You could write it : writer.append(System.lineSeparator()) after each read line.
As side notes :
1) Why not moving it before the loop (otherwise it is less efficient) :
FileWriter writer = new FileWriter("src/dataNew/BelgiumNew1.csv", true);
2) You should not flush and close the file at each read line as it is less efficient :
writer.append(line);
writer.flush();
writer.close();
System.out.println(line);
It should be enough :
writer.append(line);
System.out.println(line);
Keep that :
writer.flush();
writer.close();
in a finally statement such as :
FileWriter writer = new FileWriter("src/dataNew/BelgiumNew1.csv", true);
try{
// all your operations to handle the file
}
catch(Exception e){
// your exception handling
}
finally{
if (writer!=null){
writer.flush();
writer.close();
}
}
EDIT to answer to the comment :
If you have the impression that the output file contains multiple set of records, it is probably related to the append mode of the FileWriter that you used.
Replace that :
FileWriter writer = new FileWriter("src/dataNew/BelgiumNew1.csv", true);
by this to not use this mode :
FileWriter writer = new FileWriter("src/dataNew/BelgiumNew1.csv", false);
I see you are using opencsv to read your csv file. In addition to the correct answer from davidxxx you could simplyfy your code if you use the CSVWriter from opencsv to write to file. Below is an example:
import com.opencsv.CSVReader;
import com.opencsv.CSVWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
public class Example1 {
public static void main(String args[]) throws IOException {
String fileName = "src/data/Belgium.csv";
CSVReader reader = new CSVReader(new FileReader(fileName), ',','"',1);
List<String[]> lines = reader.readAll();
CSVWriter writer = new CSVWriter(new FileWriter("src/data/BelgiumNew1.csv",false), ',');
for(String[] row : lines){
for(int i = 0; i< row.length; i++){
row[i] = row[i].replaceAll("T", " ")
.replaceAll("Z", "z")
.replaceAll("ActualGenerationPerUnit.mean", "")
.replaceAll("Plantname:", "")
.replaceAll("\\{", "")
.replaceAll("\\}", "");
}
writer.writeNext(row);
}
writer.flush();
writer.close();
}
}
Related
I was trying to make an assignment my teacher gave and I have to order in column a set of number rows in a text file with Java
Disclaimer: my teacher doesn't want the Scanner class for this assigment: the sample data is this:
17,10,
6, 90,
11
The result should be this:
17
10
6
90
11
My code is this:
package esercizio.prova.verifica;
import java.io.*;
public class EsercizioProvaVerifica {
public static void main(String[] args) {
//read the file and put content in a String array
String[] str={};
String line = "";
try{
BufferedReader reader = new BufferedReader(new FileReader("C:\\sorgente\\file.txt"));
int i=0;
while((line=reader.readLine())!=null || i<str.length){
line = reader.readLine();
System.out.println(line + i);
str[i]=line;
i++;
}
reader.close();
} catch(IOException e){}
// Write array on file
for (int i=0;i<str.length;i++){
System.out.println(str[i]);
}
try{
BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\sorgente\\file.txt"));
for (int i = 0; i < str.length; i++) {
bw.write(str[i] + "\n"+ "");
}
bw.close();
}catch (IOException e1){}}}
The problem is everytime I run the program, the text in the file disappears and Java returns the following output:
run:
6, 90,0
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at esercizio.prova.verifica.EsercizioProvaVerifica.main(EsercizioProvaVerifica.java:16)
C:\Users\franc\AppData\Local\NetBeans\Cache\8.2rc\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 0 seconds)
I searched for hours and I can't find the problem, Can someone help? Thanks a lot.
You initialize an empty array of length zero. The array length must be determined beforehand and cannot be changed during runtime. But since you don't know how many lines your file can have, arrays are not the right data structure. use a list instead.
Use try with resource. so you don't have to close your reader and writer manually.
While writing back you do not split the single numbers. Split each line at the commas.
Use the system line separator instead of \n so that your code behaves the same on all operating systems.
Don’t ignore exceptions, i.e don't do catch(IOException e){}
Example:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Example {
public static void main(String[] args) {
List<String> lines = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader("C:\\sorgente\\file.txt"))){
// read line by line and add to list
String line;
while ((line = reader.readLine()) != null) {
lines.add(line);
}
} catch (IOException e) {
System.err.format("IOException: %s%n", e);
}
try(BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\sorgente\\file.txt"))){
for(int i = 0; i < lines.size(); i++){
//splite each line at the commas
String[] parts = lines.get(i).split(",");
for(int k = 0; k < parts.length; k++){
//remove unnecessary spaces befor ore after comma using trim method
bw.write(parts[k].trim());
bw.write(System.lineSeparator());
}
}
}
catch (IOException e) {
System.err.format("IOException: %s%n", e);
}
}
}
You have several problems.
You try to write to an array with no allocation.
You read within the while directive as well as within the while block. This causes you to skip values.
You're not splitting the values on their delimiter (,)
You're ignoring exceptions.
Here is one way to do it. There are quite a few. This uses a single loop to do both reading and wrting.
Open up the source file and create a temporary output file.
As you read in the line
split on the remaining ,s and write out the values.
when finished, close each file and then delete the original and then rename to the original.
try {
File input = new File("C:\\sorgente\\file.txt");
File output = File.createTempFile("temp",".txt");
BufferedReader reader = new BufferedReader(new FileReader(input));
BufferedWriter writer = new BufferedWriter(new FileWriter(output));
String line = "";
while ((line = reader.readLine()) != null) {
for(String s : line.split(",")) {
writer.append(s.trim());
writer.newLine();
}
}
reader.close();
writer.close();
input.delete();
output.renameTo(input);
} catch (Exception e) {
e.printStackTrace();
}
I have to read from a text file and format the input. I'm new to java reading from files, and I don't know how to work with just some parts of what I read
Here is the initial file: http://pastebin.com/D0paWtAd
And I have to write in another file the following output:
Average,Joe,44,31,18,12,9,10
I've managed just to take everything from the file and print it to output. I would need help just in taking the output I need and print it to the screen. Any help is appreciated.
This is what I wrote up to now:
public class FileParsing {
public static String
read(String filename) throws IOException {
BufferedReader in = new BufferedReader(new FileReader("C:\\Users\\Bogdi\\Desktop\\example.txt"));
String s;
StringBuilder sb = new StringBuilder();
while((s = in.readLine())!= null) sb.append(s + "\n");
in.close();
return sb.toString();
}
If your goal is to do the specified output in another file you don't need to first get the content of your file in a StringBuilder before processing it, you can append the processed datas directly in a StringBuilder then you can write the result in a file. Here is an example that would work for the given file but you may have to modify it if the keys change in the future:
The following method will correctly process the datas from your file
public static String read(String filename) throws IOException {
BufferedReader in = new BufferedReader(new FileReader(filename));
String s;
StringBuilder sb = new StringBuilder();
while((s = in.readLine())!= null) {
String[] split1 = s.split("=");
if (split1[0].equals("name")) {
StringTokenizer tokenizer = new StringTokenizer(split1[1]);
sb.append(tokenizer.nextToken());
sb.append(",");
sb.append(tokenizer.nextToken());
sb.append(",");
} else if (split1[0].equals("index")) {
sb.append(split1[1] + ",");
} else if (split1[0].equals("FBid")) {
sb.append(split1[1]);
} else {
StringTokenizer tokenizer = new StringTokenizer(split1[1]);
String wasted = tokenizer.nextToken();
sb.append(tokenizer.nextToken() + ",");
}
}
in.close();
return sb.toString();
}
The next method will read any string to a file
public static void writeStringToFile(String string, String filePath) throws IOException {
BufferedWriter writer = new BufferedWriter(
new FileWriter(
new File(filePath)
)
);
writer.write(string);
writer.newLine();
writer.flush();
writer.close();
}
And here is a simple tests (File1.txt contains the datas from the file you shared on paste bin and I write them in another file)
public static void main(String[] args) throws Exception {
String datas = read("C:\\Tests\\File1.txt");
System.out.println(datas);
writeStringToFile(datas, "C:\\Tests\\FileOuput.txt" );
}
It will produce the exact output that you are expecting
[EDIT] #idk, apparently you have an exception executing my example, while it is working fine for me. That could only mean there is an error at data level. Here is the data sample that I used (and I believe I exactly copy the datas you shared)
And here is the result:
Good to know you are using "StringBuilder" component instead being concatenating your String values, way to go :).
More than knowledge on the Java.IO API to work with files, you will need some logic to get the results you expect. Here I came with an approach that could help you, not perfect, but can point you on how to face this problem.
//Reference to your file
String myFilePath = "c:/dev/myFile.txt";
File myFile = new File(myFilePath);
//Create a buffered reader, which is a good start
BufferedReader breader = new BufferedReader(new FileReader(myFile));
//Define this variable called line that will evaluate each line of our file
String line = null;
//I will use a StringBuilder to append the information I need
StringBuilder appender = new StringBuilder();
while ((line = breader.readLine()) != null) {
//First, I will obtain the characters after "equals" sign
String afterEquals = line.substring(line.indexOf("=") + 1, line.length());
//Then, if it contains digits...
if (afterEquals.matches(".*\\d+.*")) {
//I will just get the digits from the line
afterEquals = afterEquals.replaceAll("\\D+","");
}
//Finally, append the contents
appender.append(afterEquals);
appender.append(",");//This is the comma you want to include
}
//I will delete the last comma
appender.deleteCharAt(appender.length() - 1);
//Close the reader...
breader.close();
//Then create a process to write the content
BufferedWriter myWriter = new BufferedWriter(new FileWriter(new File("myResultFile.txt")));
//Write the full contents I get from my appender :)
myWriter.write(appender.toString());
//Close the writer
myWriter.close();
}
Hope this can help you. Happy coding!
public static void main(String[] args) {
ArrayList<String> studentTokens = new ArrayList<String>();
ArrayList<String> studentIds = new ArrayList<String>();
try {
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream(new File("file1.txt"));
BufferedReader br = new BufferedReader(new InputStreamReader(fstream, "UTF8"));
String strLine;
// Read File Line By Line
while ((strLine = br.readLine()) != null) {
strLine = strLine.trim();
if ((strLine.length()!=0) && (!strLine.contains("#"))) {
String[] students = strLine.split("\\s+");
studentTokens.add(students[TOKEN_COLUMN]);
studentIds.add(students[STUDENT_ID_COLUMN]);
}
}
for (int i=0; i<studentIds.size();i++) {
File file = new File("query.txt"); // The path of the textfile that will be converted to csv for upload
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = "", oldtext = "";
while ((line = reader.readLine()) != null) {
oldtext += line + "\r\n";
}
reader.close();
String newtext = oldtext.replace("sanid", studentIds.get(i)).replace("salabel",studentTokens.get(i)); // Here the name "sanket" will be replaced by the current time stamp
FileWriter writer = new FileWriter("final.txt",true);
writer.write(newtext);
writer.close();
}
fstream.close();
br.close();
System.out.println("Done!!");
} catch (Exception e) {
e.printStackTrace();
System.err.println("Error: " + e.getMessage());
}
}
The above code of mine reads data from a text file and query is a file that has a query in which 2 places "sanid" and "salabel" are replaced by the content of string array and writes another file final . But when i run the code the the final does not have the queries. but while debugging it shows that all the values are replaced properly.
but while debugging it shows that all the values are replaced properly
If the values are found to be replaced when you debugged the code, but they are missing in the file, I would suggest that you flush the output stream. You are closing the FileWriter without calling flush(). The close() method delegates its call to the underlying StreamEncoder which does not flush the stream either.
public void close() throws IOException {
se.close();
}
Try this
writer.flush();
writer.close();
That should do it.
I want to delete some content of file using java program as below. Is this the write method to replace in the same file or it should be copied to the another file.
But its deleting the all content of the file.
class FileReplace
{
ArrayList<String> lines = new ArrayList<String>();
String line = null;
public void doIt()
{
try
{
File f1 = new File("d:/new folder/t1.htm");
FileReader fr = new FileReader(f1);
BufferedReader br = new BufferedReader(fr);
while (line = br.readLine() != null)
{
if (line.contains("java"))
line = line.replace("java", " ");
lines.add(line);
}
FileWriter fw = new FileWriter(f1);
BufferedWriter out = new BufferedWriter(fw);
out.write(lines.toString());
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
public statc void main(String args[])
{
FileReplace fr = new FileReplace();
fr.doIt();
}
}
I would start with closing reader, and flushing writer:
public class FileReplace {
List<String> lines = new ArrayList<String>();
String line = null;
public void doIt() {
try {
File f1 = new File("d:/new folder/t1.htm");
FileReader fr = new FileReader(f1);
BufferedReader br = new BufferedReader(fr);
while ((line = br.readLine()) != null) {
if (line.contains("java"))
line = line.replace("java", " ");
lines.add(line);
}
fr.close();
br.close();
FileWriter fw = new FileWriter(f1);
BufferedWriter out = new BufferedWriter(fw);
for(String s : lines)
out.write(s);
out.flush();
out.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void main(String args[]) {
FileReplace fr = new FileReplace();
fr.doIt();
}
}
The accepted answer is great. However, there is an easier way to replace content in a file using Apache's commons-io library (commons-io-2.4.jar - you can use any latest versions)
private void update() throws IOException{
File file = new File("myPath/myFile.txt");
String fileContext = FileUtils.readFileToString(file);
fileContext = fileContext.replaceAll("_PLACEHOLDER_", "VALUE-TO-BE-REPLACED");
FileUtils.write(file, fileContext);
}
Note: Thrown IOException needs to be caught and handled by the application accordingly.
Read + write to the same file simulatenously is not ok.
EDIT: to rephrase and be more correct and specific - reading and writing to the same file, in the same thread, without properly closing the reader (and flusing the writer) is not ok.
Make sure to:
close any stream when you no longer need them
In particular before reopening it for writing.
truncate the file, to make sure it shrinks if you write less than it had.
then write the output
write individual lines, don't rely on toString.
flush and close when you are finished writing!
If you use buffered IO, you always have to ensure that the buffer is flushed at the end, or you might lose data!
I can see three problems.
First you are writing to out which I assume is System.out, not an output stream to the file.
Second, if you do write to an output stream to the file, you need to close it.
Third, the toString() method on an ArrayList isn't going to write the file like you are expecting. Loop over the list and write each String one at a time. Ask yourself whether you need to write newline characters as well.
The accepted answer is slightly wrong. Here's the correct code.
public class FileReplace {
List<String> lines = new ArrayList<String>();
String line = null;
public void doIt() {
try {
File f1 = new File("d:/new folder/t1.htm");
FileReader fr = new FileReader(f1);
BufferedReader br = new BufferedReader(fr);
while ((line = br.readLine()) != null) {
if (line.contains("java"))
line = line.replace("java", " ");
lines.add(line);
}
fr.close();
br.close();
FileWriter fw = new FileWriter(f1);
BufferedWriter out = new BufferedWriter(fw);
for(String s : lines)
out.write(s);
out.flush();
}
out.close();
catch (Exception ex) {
ex.printStackTrace();
}
}
I want to delete a specific line from a text file. I found that line, but what to do next?
Any idea?
Read file from stream and write it to another stream and skip the line which you want to delete
There is no magic to removing lines.
Copy the file line by line, without the line you don't want.
Delete the original file.
rename the copy as the original file.
Try this code.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
class Solution {
public static void main(String[] args) throws FileNotFoundException, IOException{
File inputFile = new File("myFile.txt");
File tempFile = new File("myTempFile.txt");
BufferedReader reader = new BufferedReader(new FileReader(inputFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));
String lineToRemove = "bbb";
String currentLine;
while((currentLine = reader.readLine()) != null) {
// trim newline when comparing with lineToRemove
String trimmedLine = currentLine.trim();
if(trimmedLine.equals(lineToRemove)) continue;
writer.write(currentLine + System.getProperty("line.separator"));
}
writer.close();
reader.close();
boolean successful = tempFile.renameTo(inputFile);
System.out.println(successful);
}
}
Try to read file:
public static String readAllText(String filename) throws Exception {
StringBuilder sb = new StringBuilder();
Files.lines(Paths.get(filename)).forEach(sb::append);
return sb.toString();
}
then split text from specific character (for new line "\n")
private String changeFile(){
String file = readAllText("file1.txt");
String[] arr = file.split("\n"); // every arr items is a line now.
StringBuilder sb = new StringBuilder();
for(String s : arr)
{
if(s.contains("characterfromlinewillbedeleted"))
continue;
sb.append(s); //If you want to split with new lines you can use sb.append(s + "\n");
}
return sb.toString(); //new file that does not contains that lines.
}
then write this file's string to new file with:
public static void writeAllText(String text, String fileout) {
try {
PrintWriter pw = new PrintWriter(fileout);
pw.print(text);
pw.close();
} catch (Exception e) {
//handle exception here
}
}
writeAllText(changeFile(),"newfilename.txt");
Deleting a text line directly in a file is not possible. We have to read the file into memory, remove the text line and rewrite the edited content.
Maybe a search method would do what you want i.e. "search" method takes a string as a parameter and search for it into the file and replace the line contains that string.
PS:
public static void search (String s)
{
String buffer = "";
try {
Scanner scan = new Scanner (new File ("filename.txt"));
while (scan.hasNext())
{
buffer = scan.nextLine();
String [] splittedLine = buffer.split(" ");
if (splittedLine[0].equals(s))
{
buffer = "";
}
else
{
//print some message that tells you that the string not found
}
}
scan.close();
} catch (FileNotFoundException e) {
System.out.println("An error occured while searching in file!");
}
}