I am writing a program in Java that writes several lines of information into a CSV file. I want to delete the last line of CSV file, as it is not needed. How would I do this, as the CSV file is created by a PrintWriter, and I don't believe the append method could do this.
The extra line is written because the loop continues for one extra line. This portion of the code is as follows:
public static void obtainInformation() throws IOException {
PrintWriter docketFile = new PrintWriter(new FileWriter("ForclosureCourtDockets"+startingMonth+"_"+startingDay+"_"+startingYear+"-"+endingMonth+"_"+endingDay+"_"+endingYear+".csv", true));
pageContentString = pageContentString.replace('"','*');
int i = 0;
boolean nextDocket = true;
while(nextDocket) {
nextDocket = false;
String propertyCity = "PropertyCity_"+i+"*>";
Pattern propertyCityPattern = Pattern.compile("(?<="+Pattern.quote(propertyCity)+").*?(?=</span>)");
Matcher propertyCityMatcher = propertyCityPattern.matcher(pageContentString);
while (propertyCityMatcher.find()) {
docketFile.write(i+propertyCityMatcher.group().toString()+", ");
nextDocket = true;
}
String descriptionValue = "Description_"+i+"*>";
Pattern descriptionPattern = Pattern.compile("(?<="+Pattern.quote(descriptionValue)+").*?(?=</span>)");
Matcher descriptionMatcher = descriptionPattern.matcher(pageContentString);
while (descriptionMatcher.find()) {
docketFile.write(descriptionMatcher.group().toString()+"\n");
}
i++;
}
docketFile.close();
}
public static void removeLineFromFile() {
try {
File inFile = new File("ForclosureCourtDockets"+startingMonth+"_"+startingDay+"_"+startingYear+"-"+endingMonth+"_"+endingDay+"_"+endingYear+".csv");
if (!inFile.isFile()) {
System.out.println("Parameter is not an existing file");
return;
}
//Construct the new file that will later be renamed to the original filename.
File tempFile = new File(inFile.getAbsolutePath() + ".tmp");
BufferedReader br = new BufferedReader(new FileReader("ForclosureCourtDockets"+startingMonth+"_"+startingDay+"_"+startingYear+"-"+endingMonth+"_"+endingDay+"_"+endingYear+".csv"));
PrintWriter pw = new PrintWriter(new FileWriter(tempFile));
String line = null;
//Read from the original file and write to the new
//unless content matches data to be removed.
while ((line = br.readLine()) != null) {
if (!line.trim().equals("^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^")) {
pw.println(line);
pw.flush();
}
}
pw.close();
br.close();
//Delete the original file
if (!inFile.delete()) {
System.out.println("Could not delete file");
return;
}
//Rename the new file to the filename the original file had.
if (!tempFile.renameTo(inFile))
System.out.println("Could not rename file");
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
Well, as PrintWriter is just a Writer, which can only append/write/print
So, you can't override the line which you just have written.
Several options you have :
Modify your logic to make sure you don't write the line you want to remove eventually (I think the most logical option)
After writing to file you can use another Reader(say, BufferedReader) to read it again, and then re-write it, without the line you'd like to exclude.
use RandomAccessFile and its seek method to go back and rewrite / remove the line you need.
You could do the following (this is a way to implement kiruwka's first suggestion):
1) write the first line outside of the while loop.
2) Then for each line written within the while loop first output the newline, and only subsequently output the csv line.
This way you will have duplicated code, but you won't end up with a newline at the end of the file. You can also factor out the duplicate code into a helper method.
Related
I need to read from one text file(carsAndBikes.txt) and the write in either cars.txt or bikes.txt
carsAndBikes contains a list of cars and bikes and the first character of each name is C or B (C for Car and B for Bike). So far i have that but its showing cars and bikes content. Instead of the separated content.(CARS ONLY OR BIKES ONLY)
public static void separateCarsAndBikes(String filename) throws FileNotFoundException, IOException
{
//complete the body of this method to create two text files
//cars.txt will contain only cars
//bikes.txt will contain only bikes
File fr = new File("C:\\Users\\KM\\Documents\\NetBeansProjects\\Question4\\carsAndBikes.txt");
Scanner scanFile = new Scanner(fr);
String line;
while(scanFile.hasNextLine())
{
line = scanFile.nextLine();
if(line.startsWith("C"))
{
try(PrintWriter printWriter = new PrintWriter("C:\\Users\\KM\\Documents\\NetBeansProjects\\Question4\\cars.txt"))
{
printWriter.write(line);
}
catch(Exception e)
{
System.out.println("Message" + e);
}
}
else
{
try(PrintWriter printWriter = new PrintWriter("C:\\Users\\KM\\Documents\\NetBeansProjects\\Question4\\bikes.txt"))
{
printWriter.write(line);
}
catch(Exception e)
{
System.out.println("Message" + e);
}
}
}
//close the file
scanFile.close();
}
You're checking if the input filename starts with a c instead of checking if the line read starts with a c.
You should also open both your output files before your loop, and close them both after the loop.
// Open input file for reading
File file = new File("C:\\Users\\KM\\Documents\\NetBeansProjects\\Question4\\carsAndBikes.txt");
BufferedReader br = new BufferedReader(new FileReader(file)));
// Open bike outputfile for writing
// Open cars outputfile for writing
// loop over input file contents
String line;
while( line = br.readLine()) != null ) {
// check the start of line for the character
if (line.startsWith("C") {
// write to cars
} else {
// write to bikes
}
}
// close all files
I have created a program where there is a file called groups.txt. This file contains a list of names. To delete a group, it has to exist within the file. I used the Scanner method to search through each line for the name. If it contains the line, it sets val as 1. Which triggers the val == 1 condition. What I wanted to do during this block, is try to delete groupName from the groups.txt file. To do this, I created a new txt file called TempFile which copies all the names from groups.txt EXCEPT groupName. This file is then renamed to groups.txt and the old groups.txt file is deleted.
Everything works as intended, except the renaming. The temp.txt file still exists and the groups.txt file is unchanged. I checked the boolean success, and it always returns as false. Any ideas how to solve this?
if (method.equals("delete group")){
int val = 0;
String groupName = myClient.readLine();
try {
Scanner file = new Scanner(new File("groups.txt"));
while (file.hasNextLine()){
String line = file.nextLine();
if (line.indexOf(groupName) != -1){
val = 1;
}
}
if (val == 1){
try {
File groupFile = new File("groups.txt");
File tempFile = new File("temp.txt");
BufferedReader reader = new BufferedReader(new FileReader(groupFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));
String currentLine;
System.out.println(groupName);
while ((currentLine = reader.readLine()) != null){
String trimLine = currentLine.trim();
if (trimLine.equals(groupName)){
continue;
} else {
writer.write(currentLine + System.getProperty("line.separator"));
}
}
writer.close();
reader.close();
groupFile.delete();
boolean success = tempFile.renameTo("groups.txt");
} catch (IOException f){
System.err.println("File Not Found: " + f.getMessage());
} }
} catch (FileNotFoundException f){
System.err.println("File Not Found Exception: " + f.getMessage());
}
}
CODE BEFORE THE ABOVE:
if (command.equals("group")){
String method = myClient.readLine();
if (method.equals("create group")){
String groupName = myClient.readLine();
int val = 0;
try {
Scanner file = new Scanner(new File("groups.txt"));
while (file.hasNextLine()){
String line = file.nextLine();
if (line.indexOf(groupName) != -1){
Report.error("group name already exists, please pick another");
val = 1;
}
}
} catch (FileNotFoundException f){
System.err.println("File Not Found: " + f.getMessage());
}
if (val == 0){
try {
PrintWriter out = new PrintWriter(new FileWriter("groups.txt", true));
out.println(groupName);
out.close();
} catch (IOException e){
Report.error("IOException: " + e.getMessage());
}
}
In the second part of the code, this is where I originally update the groups.txt file. So every time the user adds a group, it updates the groups.txt file by adding the new groupName to the end of the file. First, I make sure the groupName doesn't already exist using Scanner. myClient is a BufferedReader which reads from another class which stores what the user types in the command line.
Also do not forget to close Scanner. First you should make delete() work and make sure you know your current working directory, and write your filepath relative to it. Check with:
File file = new File("abc.txt");
System.out.println(file.getAbsolutePath());
One thing might be unrelated, also check your environment because
In the Unix'esque O/S's you cannot renameTo() across file systems. This behavior is different than the Unix "mv" command. When crossing file systems mv does a copy and delete which is what you'll have to do if this is the case. The same thing would happen on Windows if you tried to renameTo a different drive, i.e. C: -> D:
This question already has answers here:
Write a file in UTF-8 using FileWriter (Java)?
(9 answers)
Closed 5 years ago.
Below is my code, it is intended to take two .ckl files, compare the two, add the new items and create a new merged file. The program executes correctly when run in Netbeans however, when executing the .jar the program doesn't appear to be encoding the file in UTF-8. I am rather new to programming and would like to know where or how I might need to be enforcing this encoding to take place?
** I have removed the Swing code and other lines so that only my method is shown, the method that does all of the comparing and merging.
public void mergeFiles(File[] files, File mergedFile) {
ArrayList<String> list = new ArrayList<String>();
FileWriter fstream = null;
BufferedWriter out = null;
try {
fstream = new FileWriter(mergedFile, false);
out = new BufferedWriter(fstream);
} catch (IOException e1) {
e1.printStackTrace();
}
// Going in a different direction. We are using a couple booleans to tell us when we want to copy or not. So at the beginning since we start
// with our source file we set copy to true, we want to copy everything and insert vuln names into our list as we go. After that first file
// we set the boolean to false so that we dont start copying anything from the second file until it is a vuln. We set to true when we see vuln
// and set it to false if we already have that in our list.
// We have a tmpCopy to store away the value of copy when we see a vuln, and reset it to that value when we see an </VULN>
Boolean copy = true;
Boolean tmpCopy = true;
for (File f : files) {
textArea1.append("merging files into: " + mergedFilePathway + "\n");
FileInputStream fis;
try {
fis = new FileInputStream(f);
// BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(mergedFile), "UTF-8"));
BufferedReader in = new BufferedReader(new InputStreamReader(fis));
String aLine;
while ((aLine = in.readLine()) != null) {
// Skip the close checklist and we can write it in at the end
if (aLine.trim().equals("</iSTIG>")) {
continue;
}
if (aLine.trim().equals("</STIGS>")) {
continue;
}
if (aLine.trim().equals("</CHECKLIST>")) {
continue;
}
if (aLine.trim().equals("<VULN>")) {
// Store our current value of copy
tmpCopy = copy;
copy = true;
String aLine2 = in.readLine();
String aLine3 = in.readLine();
String nameLine = in.readLine();
if (list.contains(nameLine.trim())) {
textArea1.append("Skipping: " + nameLine + "\n");
copy = false;
while (!(aLine.trim().equals("</VULN>"))) {
aLine = in.readLine();
}
continue; // this would skip the writing out to file part
} else {
list.add(nameLine.trim());
textArea1.append("::: List is now :::");
textArea1.append(list.toString() + "\n");
}
if (copy) {
out.write(aLine);
out.newLine();
out.write(aLine2);
out.newLine();
out.write(aLine3);
out.newLine();
out.write(nameLine);
out.newLine();
}
} else if (copy) {
out.write(aLine);
out.newLine();
}
// after we have written to file, if the line was a close vuln, switch copy back to original value
if (aLine.trim().equals("</VULN>")) {
copy = tmpCopy;
}
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
copy = false;
}
// Now lets add the close checklist tag we omitted before
try {
out.write("</iSTIG>");
out.write("</STIGS>");
out.write("</CHECKLIST>");
} catch (IOException e) {
e.printStackTrace();
}
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Java has extensive, highly informative documentation. Keep it bookmarked. Refer to it first, whenever you have difficulty. You'll find it's frequently helpful.
In this case, the documentation for FileWriter says:
The constructors of this class assume that the default character encoding and the default byte-buffer size are acceptable. To specify these values yourself, construct an OutputStreamWriter on a FileOutputStream.
If you want to be sure your file will be written as UTF-8, replace this:
FileWriter fstream = null;
BufferedWriter out = null;
try {
fstream = new FileWriter(mergedFile, false);
with this:
Writer fstream = null;
BufferedWriter out = null;
try {
fstream = new OutputStreamWriter(new FileOutputStream(mergedFile), StandardCharsets.UTF_8);
For those, who use FileWriter in order to append to an existing file, the following will work
try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true), StandardCharsets.UTF_8)) {
//code
}
You can just run it with the command java -Dfile.encoding=UTF-8 -jar yourjar.jar.
Follow this for more info.
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();
}
I have two files say
abc
cdg
sfh
drt
fgh
and another file
ahj
yuo
jkl
uio
abc
cdg
I want to compare these two files and get output file as
abc
cdg
sfh
drt
fgh
ahj
yuo
jkl
uio
this is my code
public static void MergeFiles(final File priviousModifiedFilesList, final File currentModifiedFilesList,
final File ModifiedFilesList) {
FileWriter fstream = null;
out = null;
try {
fstream = new FileWriter(ModifiedFilesList, true);
out = new BufferedWriter(fstream);
}
catch (IOException e1) {
e1.printStackTrace();
}
System.out.println("merging: " + priviousModifiedFilesList + "\n");
System.out.println("merging: " + currentModifiedFilesList);
FileInputStream fis1;
FileInputStream fis2;
try {
fis1 = new FileInputStream(priviousModifiedFilesList);
BufferedReader bufferedReader1 = new BufferedReader(new InputStreamReader(fis1));
fis2 = new FileInputStream(currentModifiedFilesList);
BufferedReader bufferedReader2 = new BufferedReader(new InputStreamReader(fis2));
String Line1;
String Line2;
while (((Line1 = bufferedReader1.readLine()) != null)) {
while ((Line2 = bufferedReader2.readLine()) != null) {
if (Line1.equals(Line2)) {
out.write(Line1);
}
out.write(Line2);
out.newLine();
}
out.write(Line1);
}
bufferedReader1.close();
bufferedReader2.close();
}
catch (IOException e) {
e.printStackTrace();
}
out.close();
}
it writes all the lines from first file and when the lines match it stops.
It's easy:
Read you first file line by line (you can use a Scanner for that).
For each line, write it to the output file (you can use a PrintWriter for that).
Also store the line in a HashSet.
Read your second file line by line.
For each line, check if the line is in the HashSet.
If it's not, write it to the output file.
Close your files.