The goal of my code is to replace a certain text value within my .CSV file with the user input of a text field.
My .CSV file has values delimited by commas: hey,hi. If I'm just wanting to replace 'hey' then I would gather the input from the text field and replace 'hey' with 'bye'. Output: bye,hi.
In my code, I believe I am reading in my file and writing the contents of the file to a list, delimited by commas.
I will then iterate through the list and replace an instance of the user input within the list, with another user input and write it back to file.
However, I cannot write it back to file as I'm getting the Object[] cannot be converted to String[] error. Thus I'm stuck as to how to replace the instance of user input within the text file.
Here's my code:
try{
//Convert user input into strings
String strSerial = editSerialField.getText();
String strLocation = editLocationField.getText();
//Read existing file
CSVReader reader = new CSVReader(new FileReader("test test.txt"), ',');
List myEntries = reader.readAll();
//Iterate through my array
for (int i = 0; i < myEntries.size(); i++)
{
//If an entry matches the user input
if (myEntries.get(i).equals(strSerial))
{
//Set the match to the user input from strLocation
myEntries.set(i, strLocation);
break;
}
}
//Write to existing file
CSVWriter writer = new CSVWriter(new FileWriter("test test.txt"), ',');
//Error is here**********************
//Write the new string with the replaced word OVER the same file
writer.writeNext(myEntries.toArray(new String[myEntries.size()]));
writer.close();
}catch (IOException e)
{
System.out.println(e);
}
}
How do I modify my code so that it writes my changes to the .CSV file?
For a start writeNext will write on line at a time, so you need to loop.
Secondly consider using not a raw List but using generics.
Thirdly, it may be cleaner to write as you go
and lastly, each line will contain an Array of Strings
consider this code (not tested)
CSVReader reader = new CSVReader(new FileReader("test test.txt"), ',');
List<String []> myEntries = reader.readAll();
reader.close ();
CSVWriter writer = new CSVWriter(new FileWriter("test test.txt"), ',');
//Iterate through my array
for (String [] line : myEntries)
{
ArrayList<String> newLine = new ArrayList <String>();
for (String word : line) {
{
String newVal = word.replace(strSerial, strLocation);
newLine.add (newVal);
}
writer.writeNext(newLine.toArray(new String[newLine.size()]));
}
Your problem is/ starts at this line:
List myEntries = reader.readAll();
I assume that you did not noticed that the return type of the method readAll() is
List<String[]>
If for example your test file looks like :
hey, hi
hallo, hello
sth, sthelse
After calling readAll() your variable myEntries will be a list of string arrays; each array representing each row in your file and each string from that row as element of the array
myEntries : [hey, hi]
[hallo, hello]
[sth, sthelse]
Keeping this in mind the next issue is
if (myEntries.get(i).equals(strSerial))
where you try to compare a String[] with a String which will not be true.
Try it as follows :
try{
//Convert user input into strings
String strSerial = editSerialField.getText();
String strLocation = editLocationField.getText();
CSVReader reader = new CSVReader(new FileReader("test test.txt"), ',');
// valid but not a good practice how you declare your variable before
// List myEntries = reader.readAll(); // List of what??
List<String[]> myEntries = reader.readAll();
for (String[] row : myEntries){ // go through each array from your list representing a row in your file
for (int i = 0; i < row.length; i++){ //go through each element of that array
if (row[i].equalsIgnoreCase(strSerial)){
row[i] = strLocation;
}
}
}
//add the parameter CSVWriter.NO_QUOTE_CHARACTER to prevent opencsv from writing quotes to file
CSVWriter writer = new CSVWriter(new FileWriter("test test.txt"), ',',CSVWriter.NO_QUOTE_CHARACTER);
for (String[] row : myEntries){
writer.writeNext(row);
}
writer.close();
}catch (IOException e){
System.out.println(e);
}
Not really important but i would prefer test.csv instead of test.txt as file name as long as you store comma-separated values in there.
Related
so I have a text file and i am trying to read line by line and then populate my array list.
a sample text file is shown below:
10,11,11/10/2021,24,1,2
11,12,11/10/2021,1,2,3
12,13,11/10/2021,24,5
13,14,11/10/2021,1,11,32,2
14,15,11/10/2021,1,9,8
I have been able to read in the first 4 elements (ID,ID,date,price)
and then i need to populate the other elements on that line into an array list (all elements after price)
the problem I am having is that it populates all the other lines into the array list and just not the remaining elements for the one line.
here is the code
int ID = 0;
int spareID = 0;
String date = "";
float fee = 0;
ArrayList<String> limits = new ArrayList<String>();
ArrayList<Import> imports= new ArrayList<Imports>();
File myfile = new File("file.txt");
try {
Scanner inputFile = new Scanner(myfile);
inputFile.useDelimiter(",");
// setting comma as delimiter pattern
while (inputFile.hasNextLine()) {
ID = inputFile.nextInt();
SpareID = inputFile.nextInt();
date = inputFile.next();
fee = inputFile.nextFloat();
while (inputFile.hasNext()) {
limits.add(inputFile.next());
}
Import import = new Import(ID, spareID, fee, date, limits);
imports.add(import);
}
inputFile.close();
} catch (FileNotFoundException e) {
System.out.println("error: can not find file");
}
the array list is capturing the rest of the text file when i need it to capture just the remaining elements on that line.
Edit: the first 4 elements of the line will all go into a different variable and then I need the rest or the elements on that line only to go into the array list
Use Scanner.nextLine() to get a single line, then create a second Scanner with that line to parse it contents.
Scanner inputFile = new Scanner(myfile);
while (inputFile.hasNextLine()) {
Scanner line = new Scanner(inputFile.nextLine());
// setting comma as delimiter pattern
line.useDelimiter(",");
ID = line.nextInt();
SpareID = line.nextInt();
date = line.next();
fee = line.nextFloat();
while (line.hasNext()) {
limits.add(line.next());
}
}
inputFile.close();
I'm going to do a Java library on a simple data frame that can read CSV files, edit the CSV and export CSV file. My problem is on how to export it.
Here is how I read my CSV file:
String line;
List dataFrame = new ArrayList();
String filePath = "C:\\Users\\user\\Desktop\\SimpleDataFrame\\src\\Book1.csv";
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
while ((line = br.readLine()) != null) {
List values = Arrays.asList(line.split(String.valueOf(",")));
dataFrame.add(values);
}
} catch (Exception e) {
System.out.println(e);
}
And this is how I implement the write CSV file:
FileWriter writer = new FileWriter(new File("Book2.csv"));
for(int i = 0; i<dataFrame.size(); i++){
String[] array = (String [])dataFrame.get(i);
for(int j = 0; j<array.length; j++){
writer.write(array[j]);
if(j<array.length-1) writer.write(",");
else writer.write("\n");
}
}
And this is the exception that it throws to me:
Exception in thread "main" java.lang.ClassCastException: class java.util.Arrays$ArrayList cannot be cast to class [Ljava.lang.String; (java.util.Arrays$ArrayList and [Ljava.lang.String; are in module java.base of loader 'bootstrap')
Can I know what is the problem?
In one method you have:
List values = Arrays.asList(line.split(String.valueOf(",")));
dataFrame.add(values);
So here values is a List
Then in the write method you have:
String[] array = (String [])dataFrame.get(i);
String[] is different from List that's why you have an error when you try to cast it.
It would be better if in top you do:
List<String> values = Arrays.asList(line.split(String.valueOf(",")));
dataFrame.add(values);
Adding generics. Then in the write method something like:
List<String> stringList = (List<String>) dataFrame.get(i); //Add generics to data frame here so you don't need that cast!
for(int j = 0; j<stringList.size(); j++){
writer.write(stringList.get(j));
if(j<stringList.size()-1) writer.write(",");
else writer.write("\n");
}
The problem here is your use of rawtypes. Lists in java are generic, and you have to specify the element type you want to use. Also, Lists are not interchangeable with arrays, and cannot directly cast to arrays.
List dataFrame = new ArrayList();
should trigger a warning, and you should not ignore this warning.
Based on your usage, it has to be a
List<List<String>> dataFrame = new ArrayList<>();
The elements are Lists, because you explicitly convert them from arrays to Lists in
List values = Arrays.asList(line.split(String.valueOf(",")));
String.split returns a String[], which you convert to a List with Arrays.asList.
This line should be
List<String> values = Arrays.asList(line.split(","));
(you don't need String.valueOf here, the literal is already a String).
And then in
String[] array = (String [])dataFrame.get(i);
you get a runtime exception because dataFrames contains Lists, not arrays String[]. This can be rewritten as, for example using enhanced for loop and String.join, and wrapping the writer in a try-with-resources, so that you can't forget closing it.
try (FileWriter writer = new FileWriter(new File("Book2.csv"))) {
for (List<String> list : dataFrame) {
writer.write(String.join(",", list));
writer.write("\n");
}
} catch (IOException e) {
e.printStackTrace();
}
Here is a look at the function I have been messing with for a day now. For some reason it writes the last value in the csv over and over as opposed to parsing through the rows. I threw in some print statements and it appears the row contents are correctly writing to the array but are being over written by the last value. Any help would be amazing, thanks.
public int csvCombine(ArrayList <Indexstruct> todaysCSV, int totalconvo, String date) throws IOException{
String rows = null;
Indexstruct templist=new Indexstruct();
String [] rowArray= new String [2];
FileReader fr = new FileReader(date + ".csv");
BufferedReader br = new BufferedReader(fr);
rows= br.readLine();
rowArray=rows.split(",");
totalconvo+=Integer.parseInt(rowArray[0]); //Reads in total amount of words spoken and adds it to the CSV value of words spoken
final int csvSize=Integer.parseInt(rowArray[1]); //Read in size of csvList
for(int count=0; count<csvSize-1; count++){
rows = br.readLine();
rowArray = rows.split(","); // Reads lines into an array, takes array values and places them into an object of type indexStruct to write into ArrayList
templist.numOfUses=Integer.parseInt(rowArray[1]); //sets object num of uses
templist.Word=rowArray[0]; //sets object word
todaysCSV.add(count, templist); //adds object to csv ArrayList
}
br.close();
return totalconvo;
}
All you're currently doing is adding the same templist object over and over again, and so it makes sense that all data is the same. You need to create a new templist object (whatever type it is) with each iteration of the for loop.
i.e.,
for(int count=0; count < csvSize-1; count++) {
rows = br.readLine();
rowArray = rows.split(",");
int useCount = Integer.parseInt(rowArray[1]);
String word = rowArray[0];
// assuming a type called TempList with a constructor that looks like this
todaysCSV.add(count, new TempList(useCount, word));
}
How to get and display some lines of a csv using openCSV.
I currently have the following code :
CSVReader reader1 = new CSVReader(new FileReader(mydata_csv.getpath()));
List myDatas = reader1.readAll();
How to display one specific line ?
Maybe can I use a better way to store my datas (the csv contains lines of hundreds variables). any suggestion would be welcome.
The documentation for opencsv http://opencsv.sourceforge.net/#how-to-read seems to say that your code returns a list of String[]
in which case I would write it like so:
CSVReader reader1 = new CSVReader(new FileReader(mydata_csv.getpath()));
List<String[]> myDatas = reader1.readAll();
String[] lineI = myDatas.get(i);
for (String[] line : myDatas) {
for (String value : line) {
//do stuff with value
}
}
You should use the following code:
CSVReader reader = new CSVReader(new FileReader(mydata_csv.getpath()));
String [] nextLine;
while ((nextLine = reader.readNext()) != null) {
// nextLine[] is an array of values from the line
System.out.println(nextLine[0] + nextLine[1] + "etc...");
}
Suppose there is a file named as SUN.txt
File contains : a,b,dd,ss,
I want to make dynamic array depending upon the number of attributes in file.
If ther is a char after comma then array will be of 0-4 i.e of length 5.
In the above mentioned case there is no Char which returns 0-3 Array of length 4. I want to read the NULL after comma too.
How do i do that?
Sundhas
You should think about
Reading the file into a String
Splitting the file by separator ','
Using a list for adding the characters and convert the list to an array, when the list is filled
As Markus said, you want to do something like this..
//Create a buffred reader so that you can read in the file
BufferedReader reader = new BufferedReader(new FileReader(new File(
"\\SUN.txt")));
//The StringBuffer will be used to create a string if your file has multiple lines
StringBuffer sb = new StringBuffer();
String line;
while((line = reader.readLine())!= null)
{
sb.append(line);
}
//We now split the line on the "," to get a string array of the values
String [] store = sb.toString().split(",");
I do not quite understand why you would want the NULL after the comma? I am assuming that you mean after the last comma you would like that to be null in your array? I do not quite see the point in that but that is not what the question is.
If that is the case you wont read in a NULL, if after the comma there was a space, you could read that in.
If you would like a NULL you would have to add it in yourself at the end so you could do something like
//Create a buffred reader so that you can read in the file
BufferedReader reader = new BufferedReader(new FileReader(new File(
"\\SUN.txt")));
//Use an arraylist to store the values including nulls
ArrayList<String> store = new ArrayList<String>();
String line;
while((line = reader.readLine())!= null)
{
String [] splitLine = line.split(",");
for(String x : splitLine)
{
store.add(line);
}
//This tests to see if the last character of the line is , and will add a null into the array list
if(line.endsWith(","))
store.add(null);
}
String [] storeWithNull = store.toArray();
Well if you want want to simply open the file and store the content in a array of string then
1) open the file into a string
2) split the string using a regex "," http://download.oracle.com/javase/1.5.0/docs/api/java/lang/String.html#split(java.lang.String)
but I'm curious why you can't use a String file directly ?
For your datatructure, use a list of arrays. Each list entry is a line of your textfile, each entry is an array that holds the comma separated values:
List<String[]> data = new ArrayList<String[]>();
String line = readNextLine(); // custom method, to be implemented
while (line != null) {
data.add(line.split(","));
line = readNextLine();
}
(assuming, your file contains 1..n lines of comma separated values)
You may want to have it like this:
"a,b,c,d," -> {"a", "b", "c", "d", null}
Here's a suggestion how to solve that problem:
List<String[]> data = new ArrayList<String[]>();
String line = readNextLine(); // custom method, to be implemented
while (line != null) {
String[] values = new String[5];
String[] pieces = line.split(",");
for (int i = 0; i<pieces.length; i++)
values[i] = pieces[i];
data.add(values);
line = readNextLine();
}
its seems like a CSV file something like this will work assuming it has 5 lines and 5 values
String [][] value = new String [5][5];
File file = new File("SUN.txt");
BufferedReader br = new BufferedReader(new FileReader(file));
String line = null;
int row = 0;
int col = 0;
while((line = br.readLine()) != null ){
StringTokenizer s = new StringTokenizer(line,",");
while (s.hasMoreTokens()){
value[row][col] = s.nextToken();
col++;
}
col = 0;
row++;
}
i havent tested this code
Read the file, using BufferedReader, one line at the time.
Use split(",", -1) to convert to an array of String[] including also empty strings beyond the last comma as part of your array.
Load the String[] parts into a List.