BufferedWriter overwriting itself - java

I want to read in a file and create a duplicate of the file but my code only write the last line in the file. How do I make so that whenever I call write(), it writes to a new line. I want to create a new file for the duplicate so I can't add true to FileWriter constructor.
This is my code:
//Create file reader
BufferedReader iReader = new BufferedReader(new FileReader(args[1]));
//Create file writer
BufferedWriter oWriter = new BufferedWriter(new FileWriter(args[2], true));
String strLine;
//reading file
int iterate = 0;
while((strLine = iReader.readLine()) != null) {
instructions[iterate] = strLine;
}
//creating duplicate
for(int i = 0; i < instructions.length; i++) {
if(instructions[i] != null) {
oWriter.write(instructions[i]);
oWriter.newLine();
} else {
break;
}
}
try {
iReader.close();
oWriter.close();
} catch (IOException e) {
e.printStackTrace();
}

You are not incrementing iterate
int iterate = 0;
while((strLine = iReader.readLine()) != null)
{
instructions[iterate] = strLine;
iterate++;
}

You're not updating the index of the instructions array.
In addition, it's not immediately clear why you're copying the file this way anyway; why bother doing it line-by-line? Or just use a utility class, like from Apache Commons.

Related

how can I write a code to read each name in a file

I typed 3 names in the file, and I wanted to write a code to count how many times each name was repeated (Example: Alex was repeated in the file 3 times..and so on). The code I wrote only counted each name once, and this is wrong because the names were repeated more than once. Can you help me with the part that could be the cause of this problem?
public class MainClass {
public static void readFile() throws IOException {
//File file;
FileWriter writer=null;
String name, line;
List <String> list = new ArrayList <>();
int countM = 0, countAl = 0, countAh = 0;
try
{
File file = new File("\\Users\\Admin\\Desktop\\namesList.txt");
Scanner scan = new Scanner(file);
while(scan.hasNextLine()) {
line = scan.nextLine();
list.add(line);
}
for (int i=0; i<list.size(); i++)
{
name=list.get(i);
if (name.equals("Ali"))
{
countAl= +1;
}
if (name.equals("Ahmed"))
{
countAh= +1;
}
if (name.equals("Muhammad"))
{
countM = +1;
}
}
Collections.sort(list);
writer = new FileWriter("\\Users\\Admin\\Desktop\\newNameList");
for(int i=0; i<list.size(); i++)
{
name = list.get(i);
writer.write(name +"\n");
}
writer.close();
System.out.println("How many times is the name (Ali) in the file? " + countAl);
System.out.println("How many times is the name (Ahmed) in the file? " + countAh);
System.out.println("How many times is the name (Muhammad) in the file? " + countM);
}
catch(IOException e) {
System.out.println(e.toString());
}
}
public static void main(String[] args) throws IOException {
readFile();
}
}
You an do this much simpler:
//Open a reader, this is autoclosed so you don't need to worry about closing it
try (BufferedReader reader = new BufferedReader(new FileReader("path to file"))) {
//Create a map to hold the counts
Map<String, Integer> nameCountMap = new HashMap<>();
//read all of the names, this assumes 1 name per line
for (String name = reader.readLine(); name != null; name = reader.readLine()) {
//merge the value into the count map
nameCountMap.merge(name, 1, (o, n) -> o+n);
}
//Print out the map
System.out.println(nameCountMap);
} catch (IOException e) {
e.printStackTrace();
}
try:
for (int i=0; i<list.size(); i++)
{
name=list.get(i);
if (name.equals("Ali"))
{
countAl += 1;
}
if (name.equals("Ahmed"))
{
countAh += 1;
}
if (name.equals("Muhammad"))
{
countM += 1;
}
}
This works with me.
+= is not same =+
You need to process each line bearing in mind that the file may be very large in some cases. Better safe than sorry. You need to consider a solution that does not take up so much resources.
Streaming Through the File
I'm going to use a java.util.Scanner to run through the contents of the file and retrieve lines serially, one by one:
FileInputStream inputStream = null;
Scanner sc = null;
try {
inputStream = new FileInputStream(file_path);
sc = new Scanner(inputStream, "UTF-8");
while (sc.hasNextLine()) {
String line = sc.nextLine();
// System.out.println(line);
}
// note that Scanner suppresses exceptions
if (sc.ioException() != null) {
throw sc.ioException();
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (sc != null) {
sc.close();
}
}
This solution will iterate through all the lines in the file – allowing for processing of each line – without keeping references to them – and in conclusion, without keeping them in memory:
Streaming With Apache Commons IO
The same can be achieved using the Commons IO library as well, by using the custom LineIterator provided by the library:
LineIterator it = FileUtils.lineIterator(your_file, "UTF-8");
try {
while (it.hasNext()) {
String line = it.nextLine();
// do something with line
}
} finally {
LineIterator.closeQuietly(it);
}
Since the entire file is not fully in memory – this will also result in pretty conservative memory consumption numbers.
BufferedReader
try (BufferedReader br = Files.newBufferedReader(Paths.get("file_name"), StandardCharsets.UTF_8)) {
for (String line = null; (line = br.readLine()) != null;) {
// Do something with the line
}
}
ByteBuffer
try (SeekableByteChannel ch = Files.newByteChannel(Paths.get("test.txt"))) {
ByteBuffer bb = ByteBuffer.allocateDirect(1000);
for(;;) {
StringBuilder line = new StringBuilder();
int n = ch.read(bb);
// Do something with the line
}
}
The above examples will process lines in a large file without iteratively, without exhausting the available memory – which proves quite useful when working with these large files.

How to read multiple objects from a text file and then send to an ArrayList?

I currently have my program reading the first object using BufferedReader but I am unsure how to read more then one object.
Here is the code that I have reading from the file:
public Stock getData(){
StringTokenizer row;
Stock aStock = new Stock();
try{
BufferedReader inbuffer = new BufferedReader(new FileReader(fileName));
String inputString;
inputString = inbuffer.readLine();
if(inputString != null){
row = new StringTokenizer(inputString, DELIMTER);
if(row.countTokens() == 4){
aStock.setStockName(row.nextToken());
aStock.setStockQuantity(Integer.parseInt(row.nextToken()));
aStock.setPurchasePrice(Double.parseDouble(row.nextToken()));
aStock.setCurrentPrice(Double.parseDouble(row.nextToken()));
}
}
inbuffer.close();
}
catch(IOException ioe){
JOptionPane.showMessageDialog(null, ioe.getMessage(), "File Read Error", JOptionPane.ERROR);
}
return aStock;
}
The file I am reading from looks like this:
and then the section of code that calls to my bufferedReader looks like this:
public void loadFile(){
StockIO stockRead = new StockIO();
jFileChooser1.showOpenDialog(jPanel3);
File file = jFileChooser1.getSelectedFile();
stockRead.loadFileName(file.getName());
stockArr.add(stockRead.getData());
int index = 0;
if(stockArr.get(index) != null){
DLM.addElement(stockArr.get(0).getStockName());
index ++;
}
listStock.setModel(DLM);
}
So I am trying to get it where my bufferedReader will read and send both lines of code through.Currently if I run this it will send through the "Shawn" line with all object information but I want the "test" line as well. Thank you for your time looking at this.
Your code is currently stopping after it reads the first line because there is no loop to continue iterating through your whole file.
You can use a while loop to check if there is a line to read while looping through your lines:
while ((line = inbuffer.readLine()) != null) {
// Process each line
}
import java.util.ArrayList;
public ArrayList<Stock> getData(){
StringTokenizer row;
ArrayList<Stock> stockList = new ArrayList<>();
try{
BufferedReader inbuffer = new BufferedReader(new FileReader(fileName));
String inputString;
Stock aStock;
// inputString = inbuffer.readLine();
while ((line = inbuffer.readLine()) != null){
row = new StringTokenizer(line, DELIMTER);
if(row.countTokens() == 4){
aStock = new Stock();
aStock.setStockName(row.nextToken());
aStock.setStockQuantity(Integer.parseInt(row.nextToken()));
aStock.setPurchasePrice(Double.parseDouble(row.nextToken()));
aStock.setCurrentPrice(Double.parseDouble(row.nextToken()));
stockList.add(aStock);
}
}
inbuffer.close();
}
catch(IOException ioe){
JOptionPane.showMessageDialog(null, ioe.getMessage(), "File Read Error", JOptionPane.ERROR);
}
return stockList;
}
It also looks like you also need to add a loop in your loadFile() method to iterate through all of your stocks.
public void loadFile(){
StockIO stockRead = new StockIO();
jFileChooser1.showOpenDialog(jPanel3);
File file = jFileChooser1.getSelectedFile();
stockRead.loadFileName(file.getName());
// Add all new stocks from getData to stockArr
stockArr.addAll(stockRead.getData());
// int index = 0;
for (int index = 0; index < stockArr.length; index++) {
if(stockArr.get(index) != null){
DLM.addElement(stockArr.get(index).getStockName());
}
}
listStock.setModel(DLM);
}

bufferedReader readline=null

im trying to write a class where it would take a text file,reverse its contents and write it back. The way i want to do it is to write the lines in a String[] array,reverse the lines and then write the text back to the text file. Problem is, when I start writing to the String array, it writes off only nulls and i know the text file is not empty. Im using a copy of the BufferedReader to read the lines. I can't seem to understand where am i wrong. When I initialize the String array textFile like down in the code, i have no problems reversing, but when i use the
String[] textFile = new String[getNumberOfLines ()];
method, it doesnt work.
public void reverse() throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(WORK_FOLDER_LOCATION + FILE_NAME));
String[] textFile = new String[3];
try {
for (int i = 0; i < textFile.length; i++) {
textFile[i] = reader.readLine();
textFile[i] = reverseLine(textFile[i]);
}
} catch (IOException e) {
throw new IOException("There was a problem while operating with the reader.");
} finally {
reader.close();
}
writeReverseText(textFile);
}
private int getNumberOfLines(BufferedReader reader) throws IOException {
BufferedReader linesReader = reader;
int counter = 0;
try {
while (linesReader.readLine() != null) {
counter++;
}
linesReader.close();
} catch (IOException e) {
throw new IOException("There was a problem while counting the lines");
}
return counter;
}
private String reverseLine(String string) {
StringBuilder reversedString = new StringBuilder(string).reverse();
System.out.println(reversedString);
return reversedString.toString();
}
private void writeReverseText(String[] textFile) throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter(WORK_FOLDER_LOCATION + FILE_NAME));
for (int i = 0; i < textFile.length; i++) {
writer.append(textFile[i]);
writer.append(System.lineSeparator());
}
writer.close();
}
EDIT I managed to solve the issue but changing the getNumberOfLines() method:
private int getNumberOfLines() throws IOException {
BufferedReader linesReader = new BufferedReader(new FileReader(WORK_FOLDER_LOCATION + FILE_NAME));
Hope this helps to the others, i would love to know why the previous code didn't work.
Your getNumberOfLines() method will read all the data from the BufferedReader - so unless you start reading the file again, there's nothing to read, and the very first call to readLine() will return null.
However, instead of doing this, you'd be better off just reading the file once, and populating a List<String>. For example:
List<String> lines = new ArrayList<>();
String line;
while ((line = reader.readLine()) != null) {
lines.add(reverseLine(line));
}

Read CSV file and write back CSV File based on condition

I'm new to java. I'm required to read The input data(csv)(large number of records) I receive in the given below format:
A,1
A,2
B,3
B,4
C,5
C,6
A,7
A,8
B,9
B,10 ...
I'm using PrintWriter to write the data into the new CSV file. Is there a.ny way I can write into the new csv file this way from the above data? Here the condition is based on values A, B,C.
A,B,C
1,3,5
2,4,6
7,9
8,10...
I think this is possible if there are always A,B and C. But this idea can be extended to finite number of constants
What you can do is something like...
public void computeNewCSV() {
List<Integer> a = new LinkedList<Integer>();
List<Integer> b = new LinkedList<Integer>();
List<Integer> c = new LinkedList<Integer>();
FileInputStream fis = new FileInputStream("input_file");
BufferedReader br = new BufferedReader(new InputStreamReader(fis, Charset.forName("UTF-8")));
String line;
while ((line = br.readLine()) != null) {
String split[] = line.split(",");
if(split[0].equals("A") {
a.add(Integer.parseInt(split[1]));
} else if (split[0].equals("B") {
b.add(Integer.parseInt(split[1]));
} else if (split[0].equals("C") {
c.add(Integer.parseInt(split[1]));
}
}
br.close();
fis.close();
//Now you have the complete information to be put into the new file.
PrintWriter writer = new PrintWriter("output-file-name", "UTF-8");
writer.println("A,B,C");
while(!(a.isEmpty && b.isEmpty() && c.isEmpty())) {
StringBuilder sb = new StringBuilder("");
if(!a.isEmpty()) {
sb.append(a.remove(0));
}
sb.append(",");
if(!b.isEmpty()) {
sb.append(b.remove(0));
}
sb.append(",");
if(!c.isEmpty()) {
sb.append(c.remove(0));
}
writer.println(sb.toString());
}
writer.close();
}

overwriting a file in java using FileWriter

I have to accomplish a task of writing a set of data to file, use it, then overwrite it with new data. Thus overwrite of the file takes place repeatedly.I know i can accomplish the above by creating FileWriter object each time with the option to overwrite like below
FileWriter object = new FileWriter("fileName", false)
and close it to write to the file.
If i am supposed to overwrite the file n number of times , according to the above method i need to create n number of FileWriter objects. Is there any efficient way to overwrite a file repeatedly by only creating a single FileWriter object?
Not a direct answer, but anyway.
DON'T DO THAT!
What do you think will happen if for some reason writing the new data to the file fails?
You not only lose your original file, but also the new file contents...
Write the new content to another file, ensure that it is well written and closed, and then rename the new file atomically to the original file.
PS: and do not forget to correctly .close().
PS2: if you use Java 7, use the new Files API.
Its better to make a temp file and then rename the tempfile and delete the old like here:
public static void nachtragenTRA(File files) throws IOException{
Scanner sc=null;
File f= files;
String analyse = "";
String NTausgabe = "";
int max = 0;
int k = 0;
String updatedLine[] = new String [4];
int filenr = 1;
boolean sucess = false;
try{
sc= new Scanner(f);
}catch(FileNotFoundException x){
System.out.println("Error: File not found!");
}
while (sc.hasNextLine()){ //get next line
analyse = sc.nextLine();
max = analyse.length(); //get line lenght
StringBuffer sb = new StringBuffer(analyse); //write analyse in StringBuffer
//to change the string
if(k == 1)
{
sb.replace(Daten.NTdatapos[3],max, Daten.NTProbentypTextfield.getText());
updatedLine[0] =String.valueOf(sb);
}
else if(k == 2)
{
sb.replace(Daten.NTdatapos[4],max, Daten.NTPrueferTextfield.getText());
updatedLine[1] =String.valueOf(sb);
}
else if(k == 3)
{
sb.replace(Daten.NTdatapos[5],max, Daten.NTKundeTextfield.getText());
updatedLine[2] =String.valueOf(sb);
}
else if(k == 4)
{
sb.replace(Daten.NTdatapos[5],max, Daten.NTWerkstoffTextfield.getText());
updatedLine[3] =String.valueOf(sb);
}
if(k>3)
{
break;
}
k++;
}
sc.close();
//NTausgabe=DatenTextarea.getText()+"\n"+updatedLine[0]+"\n"+updatedLine[1];
//DatenTextarea.setText(String.valueOf(NTausgabe));
//NTausgabe=DatenTextarea.getText()+"\n"+NTKundeTextfield.getText()+"\n"+NTPrueferTextfield.getText();
//DatenTextarea.setText(String.valueOf(NTausgabe));
//create tmp file with the new data
PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(String.valueOf(f)+".tmp")));
BufferedReader br = null;
FileReader reader = null;
try {
reader = new FileReader(String.valueOf(f));
br = new BufferedReader(reader);
String line;
while ((line = br.readLine()) != null)
{
//Change speciffic lines
if(filenr == 2)
{
writer.println(updatedLine[0]);
}
else if(filenr == 3)
{
writer.println(updatedLine[1]);
}
else if(filenr == 4)
{
writer.println(updatedLine[2]);
}
else if(filenr == 5)
{
writer.println(updatedLine[3]);
}
//Andere Zeilen beibehalten
else
{
writer.println(line);
}
filenr = filenr + 1;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
reader.close();
br.close();
File realName = new File(String.valueOf(f));
realName.delete(); //delete old file
writer.close();
sucess = new File(String.valueOf(f)+".tmp").renameTo(realName); //rename tmp File to the others name
if(sucess != true)
{
NTausgabe=Daten.DatenTextarea.getText()+"\n"+"Rename File failed";
Daten.DatenTextarea.setText(String.valueOf(NTausgabe));
}
else
{
NTausgabe=Daten.DatenTextarea.getText()+"\n"+"File renamed sucessfully";
Daten.DatenTextarea.setText(String.valueOf(NTausgabe));
}
}
}

Categories