Read and write csv file

Can i use the .csv file to store my address book information? If yes, how can i read and write the .csv files? What is the benefit of using .csv file than normal .txt file? Is't possible to make the .csv file is unreadable by user or do some encoding inside the .csv file?

thanks
KennywenAsked:
Who is Participating?
 
CEHJConnect With a Mentor Commented:
I assume those data (in the array) are for the purposes of a TableModel. You don't need to construct your TableModel from an array - you can create it from a Vector of Vectors, then you don't need to bother about counting lines.

Vector data = new Vector();
// in loop
String[] values = lineJustRead.split(",");
Vector row = new Vector();
for(int i = 0;i < values.length;i++) {
      row.add(values[i].trim()); // adjust if different data types required
}
data.add(row);

// After loop

DefaultTableModel dtm = new DefaultTableModel(data, otherVectorContainingColumnNames);
0
 
manifoldroninCommented:
CSV stands for Comma Separated Values.  That's the only thing you need to know to be able to read and write one - in the end, they are little more than regular text files.
Anything you can/can't do to/with a text file you can/can't do to/with a csv file.
0
 
KennywenAuthor Commented:
any other tool that allow us to store the address book information with the encoding or make the file is unreable by user?

thanks
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
KennywenAuthor Commented:
But i don't want to use mysql or other databases.
0
 
manifoldroninCommented:
You can use XML which supports encoding and structural query.  It still doesn't have any built-in feature to prevent particular users from reading it, but you can always set the access rights at the OS level, can't you?
0
 
KennywenAuthor Commented:
Can u give me some example so that i can learn from it. BTW is't the XML support insert, delete update and select function and XML can be use in any OS?
0
 
KennywenAuthor Commented:
beside XML can anyone show me how to read and write the .csv files.

thanks
0
 
KennywenAuthor Commented:
Actually i undestand that i can use java.util.StringTokenizer to split the data when i want to read it but how can i write the data to the .csv file?
0
 
CEHJCommented:
You can encrypt any text file. Here's an example:

http://javaalmanac.com/egs/javax.crypto/PassKey.html


Writing to a csv file is as simple as writing any other file. Suppose you have each column value in an array called 'values':

// 'out' is a PrintWriter opened on a FileWriter, opened on a file
for(int i = 0;i < values.length - 1;i++) {
      out.print(values[i]);
      out.print(",")
}
out.println(values[values.length - 1]);

in your case, where 'values' appears in the print\println you'd want to call print(encrypt(values[i])) or whatever
0
 
KennywenAuthor Commented:
should i write:

PrintWriter out = null;
for(int i = 0;i < values.length - 1;i++) {
     out.print(values[i]);
     out.print(",")
}
out.println(values[values.length - 1]);

But how can i specify the file name? If the file already exist with some data so the out.println(values[values.length - 1]); will overwrite the current data in the file? If yes, how can i append it ?

thanks
0
 
CEHJCommented:
>>But how can i specify the file name?

PrintWriter out = new PrintWriter(new FileWriter("x.csv"));


>>how can i append it ?

PrintWriter out = new PrintWriter(new FileWriter("x.csv"), true);

0
 
KennywenAuthor Commented:
>> PrintWriter out = new PrintWriter(new FileWriter("x.csv"), true);

if i put true then it will append additional data into the csv file? else it will just overwrite the current data in the csv file?

why at the end i should write out.println(values[values.length - 1]);

thanks
0
 
CEHJCommented:
>>if i put true ...

Yes

>>why at the end...

Because you don't need a comma at the end of the line

0
 
KennywenAuthor Commented:
then the csv file will contain information like :
Smith Joe, M, UK, 22
Smith Joe, M, UK, 22
Smith Joe, M, UK, 22

every new data will in the different row?

Can i count there is how many rows in the csv file?

thanks
0
 
KennywenAuthor Commented:
The read file:

int counter=0;

BufferedReader buf = new BufferedReader(new FileReader(new File("data.csv);
            while ( (text = buf.readLine()) != null) {
               String split = line.split(",");
               >> how can i put the two dimensional array in here?
               counter++;
            }

thanks


0
 
CEHJCommented:
>>every new data will in the different row?

>>Can i count there is how many rows in the csv file?

why would you want to do that btw?
0
 
johnknappConnect With a Mentor Commented:
I am currently writing a software program which generates a number of different types of files, one of which is csv, and it is the easiest to create.

My preferred way is to create a data object with a similar type of method as getFields():

import java.util.Iterator;

public class DataRecord {

    private int id;
   
    private String name;
   
    private String phone;

    // regular getter setter methods
   
    public void setId(int id) { this.id = id; }
   
    public int getId() { return (id); }
   
    public void setName(String name) { this.name = name; }
   
    public String getName() { return (name); }
   
    public void setPhone(String phone) { this.phone = phone; }
   
    public String getPhone() { return (phone); }
   
    /**
     * Gets an array of all fields in the data object
     * promoted to strings for easy writing to the file
     * since CSV files are text anyway, string is the perfect
     * choice
     * @return An array of strings of all fields in the data object
     */
    public String[] getFields() {
        String[] fields = new String[3];
        fields[0] = String.valueOf(id);
        fields[1] = name;
        fields[2] = phone;
        return (fields);
    }
   
}

then create a simple writer, this one allows you to specify if you would like the fields quoted or not (depends if your data has internal commas) such as if the name field is "last, first" than you would want it quoted

import java.io.*;

public class CSVWriter {

    private File file;

    private BufferedWriter writer;
   
    private boolean quotedFields;
   
    private String pnl;
   
    public CSVWriter(File file, boolean quotedFields) {
        this.file = file;
        this.quotedFields = quotedFields;
        pnl = System.getProperty("line.separator");
    }
   
    public void open() throws IOException {
        FileWriter fw = new FileWriter(file);
        writer = new BufferedWriter(fw);
    }
   
    public void writeRecord(DataRecord dr) throws IOException {
        String[] fields = dr.getFields();
        for (int i = 0; i < fields.length; i++) {
            writer.write(wrapQuotes(fields[i]));
            if (i + i < fields.length)
                writer.write(",");
            else
                writer.write(pnl); // must be end of record so write the new line
        }
    }
   
    private String wrapQuotes(String val) {
        return ((quotedFields ? "\"" + val + "\"" : val));
    }
   
    public void close() throws IOException {
        if (writer != null) {
            writer.flush();
            writer.close();
        }
    }
   
}

then simply iterate through the collection of data records inserting commas, quote marks, and new lines as necessary

Vector records; // holds a bunch of data objects

String fileName = "mycsvfile.csv"; // the sample file name

CSVWriter csvWriter = new CSVWriter(new File(fileName), false); // constructs the writer
try {
    csvWriter.open();
    Iterator iter = records.iterator();
    while (iter.hasNext()) {
        csvWriter.writeRecord((DataRecord) iter.next());
    }
    csvWriter.close();
} catch (IOException ioe) {
   // handle io exception
}

And That is about all there is to it, you can do better and if performance is an issue this wouldn't be the perfect solution, but it works, the file would come out in the format
0,john,5555555
1,joe,5555555
2,carol,555555
etc ...

or, if we specified true in the second parameter of the CSVWriter it would look like
"0","john","5555555"
"1","joe","5555555"
"2","carol","5555555"
etc ...

either of which are valid CSV formats

If you would like to store data in a format that someone couldn't read and you just want it quick and dirty and your data object or record is serializable or externalizable you could simply open a ObjectOutputStream over a file output stream and call writeObject(Object o);

It isn't the best way to handle it, but it works (but isn't platform portable) different versions of the jre serialize objects differently.

I would however, as best practice generally look for a versitile format like XML, its verbose and sometimes impractical, but is much better for data exchange (which is generally what CSV was originally designed to do).

Hope That Helps,
John



0
 
KennywenAuthor Commented:
>> why would you want to do that btw?

i want to count there is how many rows in the files so that i can create a two dimensional array.
0
 
KennywenAuthor Commented:
I want to create two dimensional array like;
private Object[][] data = {
            {"Mary", "Campione",
             "Snowboarding", new Integer(5), new Boolean(false)},
            {"Alison", "Huml",
             "Rowing", new Integer(3), new Boolean(true)},
            {"Kathy", "Walrath",
             "Knitting", new Integer(2), new Boolean(false)},
            {"Sharon", "Zakhour",
             "Speed reading", new Integer(20), new Boolean(true)},
            {"Philip", "Milne",
             "Pool", new Integer(10), new Boolean(false)}
        };
0
 
KennywenAuthor Commented:
Please show me how to read the file and assign it to two dimensional array like:
private Object[][] data = {
            {"Mary", "Campione",
             "Snowboarding", new Integer(5), new Boolean(false)},
            {"Alison", "Huml",
             "Rowing", new Integer(3), new Boolean(true)},
            {"Kathy", "Walrath",
             "Knitting", new Integer(2), new Boolean(false)},
            {"Sharon", "Zakhour",
             "Speed reading", new Integer(20), new Boolean(true)},
            {"Philip", "Milne",
             "Pool", new Integer(10), new Boolean(false)}
        };


my sample file:
BufferedReader buf = new BufferedReader(new FileReader(new File("data.csv);
            while ( (text = buf.readLine()) != null) {
               String split = line.split(",");
               >> how can i put the two dimensional array in here?
               counter++;
            }

thanks
0
 
WebstormCommented:
>>  if (i + i < fields.length)
You probably mean :
    if (i + 1 < fields.length)

0
 
WebstormConnect With a Mentor Commented:
Hi Kennywen,

You need to count the number of lines:

            BufferedReader buf = new BufferedReader(new FileReader(new File("data.csv);
            while ( (text = buf.readLine()) != null) {
               if (text.trim().length()>0)   counter++; // count non-empty lines
            }

Then you can store data in the array :

            data = new Object[counter][5];
            BufferedReader buf = new BufferedReader(new FileReader(new File("data.csv);
            counter=0;
            while ( (text = buf.readLine()) != null) {
               text=text.trim();
               if (text.length()==0)  continue; // empty line
               String[] split = line.split(",");
               for (int j=0;j<5;j++) // for each field:
               {
                   switch(j)
                   {
                       case 3: data[counter] = new Integer(text); break;
                       case 4: data[counter] = new Boolean(text); break;
                       default: data[counter] = text; break;
               }
                counter++;
            }
0
 
WebstormCommented:
Replace :
           BufferedReader buf = new BufferedReader(new FileReader(new File("data.csv);
By :
           BufferedReader buf = new BufferedReader(new FileReader("data.csv"));
0
 
KennywenAuthor Commented:
How can i update and delete the information in the csv file?

thanks
0
 
KennywenAuthor Commented:
Is't possible to perform update and delete in the csv file without using sql statement?

thanks
0
 
KennywenAuthor Commented:
is't possible just delete a specify line in the csv file?
0
 
johnknappCommented:
It the csv file is not that large why not cache it all in memory and then rewrite it when you are finished modifying it,

and why would you be using a SQL statement?
0
 
KennywenAuthor Commented:
>> why would you be using a SQL statement?

because i just afraid i cannot delete or update the csv file without using sql statement.
0
 
johnknappCommented:
I guess the question is what exactly are you trying to achieve by using a CSV file?  What data and how much of it are you trying to store.  CSV Files are really designed for quick write and read not really for modifications.  The strong point about using csv is easy implementation, for more sophisticated operations on files I would recommend possibly keeping an index into the file stored separately - a record, byte location kind of key file and then make sure modifications to the csv file always happen through the same interface to make sure the index stays correct with the file.
0
 
johnknappCommented:
I am not sure if the scope of your original question has changed, and I am still unclear as to how you would even use a SQL query to perform an operation on a CSV file . . . are you using a JDBC driver that operates on CSV files?

Which I have never heard of myself.

If you want to change a CSV file and then save it and it is not a huge file, say under 10,000 records or so try something like this . . .

1) read file into 2 dimensional object array (is that the data type you want to use?)

2) modify the elements accordingly

3) rewrite the file, ie open the file writer with ...
FileWriter fileWriter = new FileWriter("somecsvfile.csv", false); // so as to completely write over the existing file

4) reiterate over you modified object array and write out each element.
Object[][] some2dArray; // initialized elsewhere, say an array of strings for sake of example
BufferedWriter writer = new BufferedWriter(fileWriter); // since this will give us easy string processing
for (int i = 0; i < some2dArray.length; i++) {
    for (int inner = 0; inner < some2dArray[i].length; inner++) {
        writer.write(some2dArray[i][inner].toString());
        if (inner + 1 < some2dArray[i].length)
            writer.write(",");
        else
            writer.write(System.getProperty("line.separator", "\n"));
    }
}
writer.flush();
writer.close();

// handle all IOExceptions omitted for clarity
0
 
KennywenAuthor Commented:
So i need to write the csv file to some2dArray first and then change the value (if user press the edit button) or delete the value (if user press delete button) and then write it into the file again?

thanks
0
 
johnknappCommented:
Sort of,

The user will be operating on the array for some amount of time correct? When the user is finished this is when you commit the changes to the file.

So this way (I am assuming this is kind of what you were talking about in pseudo-pseudo code)

1) User opens program component

2) Load the file into a 2d object array or whatever data structure you feel is appropriate

3) User clicks edit button or delete button

4) Modify array

5) User repeats process 3 n times, each time your code repeats 4 n times

6) User finishes editing

7) resave file
0
 
KennywenAuthor Commented:
No, i will not load the file into a 2d object array when user run the program.
The csv file is to keep the address book information. so when the user press edit button then a pop up window will display then the user can edit it. once the user press ok button then i will  Load the file into a 2d object array.

Can i use the above approach?

thanks
0
 
KennywenAuthor Commented:
Object[] data = new Object[3];
data[0] = new String(nameField.getText());
data[1] = new String(mobileField.getText());
data[2] = new String(emailField.getText());

PrintWriter out = new PrintWriter(new FileWriter("phone.csv"), true);
for(int i = 0;i < data.length - 1;i++) {
      out.print(data[i]);
      out.print(",");
}
out.println(data[data.length - 1]);

The above code will not append the file. why?
0
 
KennywenAuthor Commented:
i get the answer, i should use:

PrintWriter out = new PrintWriter(new BufferedWriter( new FileWriter ("phone.csv", true)));

0
 
johnknappCommented:
one quick thing with your sample code,

Make sure if your data has any possibility of ever having a comma embedded in the field (seems unlikely in your case unless the name field is last,first)

to wrap the data in quotes
such as
"name","mobile","email"
"name2","mobile2","email2"

otherwise you will have troubles reading it (but only in the case that your data could contain embedded commas)
0
 
KennywenAuthor Commented:
Object[][] data = new Object[counter][3];
            BufferedReader buf1 = new BufferedReader(new FileReader("phone.csv"));
            counter=0;
            while ( (text = buf1.readLine()) != null) {
               text=text.trim();
               if (text.length()==0)  continue; // empty line
               String[] split = text.split(",");
               for (int j=0;j<5;j++) // for each field:
               {
                   switch(j)
                   {
                       //case 3: data[counter] = new Integer(text); break;
                       //case 4: data[counter] = new Boolean(text); break;
                       default: data[counter] = split[j]; break;
                           }
               }
                counter++;
            }

an error occur:
BoxAlignmentDemo.java:588: incompatible types
found   : java.lang.String
required: java.lang.Object[]
default: data[counter] = split[j]; break;
                                         ^
1 error
0
 
WebstormCommented:
Replace :
  data[counter] =
By :
  data[counter][j] =
0
 
johnknappCommented:
You can't assign a string to an object array reference

you should do

data[counter][j] = split[j];

or in context

default: data[counter][j] = split[j]; break;

try that, but why the switch (j) if you aren't using the switch construct for what it is useful for?
0
 
CEHJCommented:
You can use a class like this to add/delete lines in a csv file. e.g.:

StringList sl = new StringList("your.csv");
sl.remove(1); // remove first line after column headers





SNIP==================================

import java.io.*;
import java.util.ArrayList;

  public class StringList extends ArrayList {

  public StringList() {
    super();
  }

  public StringList(String fileName) {
    this();
    String line = null;
    BufferedReader in = null;
    try {
      in = new BufferedReader(new FileReader(fileName));
      while ((line = in.readLine()) != null) {
        add(line);
      }
    }
    catch (IOException e) {
      e.printStackTrace();
    }
    finally {
      try {
        in.close();
      }
      catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
}
0
 
KennywenAuthor Commented:
thanks to all
0
 
CEHJCommented:
8-)
0
 
WebstormCommented:
:-)
0
 
geckomaniak44Commented:
There's a few jdbc drivers that you can use rather than such a low level solution.
For read-only, I've had good success with csvjdbc.jar. There are a few of them at sourceforge.

HTH - rich
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.