Hướng Dẫn Xử Lý Tệp CSV Toàn Diện trong Java
Tệp CSV (Comma-Separated Values) là một định dạng phổ biến để lưu trữ dữ liệu, thường được sử dụng trong các ứng dụng phân tích dữ liệu và truyền tải thông tin giữa các hệ thống khác nhau. Bài viết này sẽ hướng dẫn bạn cách xử lý tệp CSV bằng Java, bao gồm cả việc sử dụng Java thuần và thư viện OpenCSV.
Mục Lục
- Sử Dụng Java Thuần
- Sử Dụng OpenCSV
- So Sánh: Java Thuần vs OpenCSV
- Thực Hành Tốt Nhất
- Mẹo Hiệu Suất
- Khắc Phục Sự Cố
1. Sử Dụng Java Thuần
Đọc Tệp CSV
Để đọc tệp CSV bằng Java thuần, bạn có thể sử dụng lớp BufferedReader như sau:
java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class DocCSV {
public static void main(String[] args) {
String csvFile = "data.csv";
String line = "";
String csvDelimiter = ","; // Dấu phẩy là dấu phân cách mặc định trong tệp CSV
List<String[]> data = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
// Đọc dòng tiêu đề
String headerLine = br.readLine();
if (headerLine != null) {
String[] headers = headerLine.split(csvDelimiter);
System.out.println("Tiêu đề: " + String.join(", ", headers));
}
// Đọc các dòng dữ liệu
while ((line = br.readLine()) != null) {
String[] values = parseCSVLine(line, csvDelimiter);
data.add(values);
System.out.println("Dòng: " + String.join(" | ", values));
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Tổng số dòng đã đọc: " + data.size());
}
private static String[] parseCSVLine(String line, String delimiter) {
List<String> values = new ArrayList<>();
StringBuilder currentValue = new StringBuilder();
boolean inQuotes = false;
for (int i = 0; i < line.length(); i++) {
char c = line.charAt(i);
if (c == '"') {
inQuotes = !inQuotes;
} else if (c == delimiter.charAt(0) && !inQuotes) {
values.add(currentValue.toString());
currentValue = new StringBuilder();
} else {
currentValue.append(c);
}
}
values.add(currentValue.toString());
return values.toArray(new String[0]);
}
}
Ghi Tệp CSV
Để ghi tệp CSV, bạn có thể sử dụng lớp BufferedWriter như sau:
java
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class GhiCSV {
public static void main(String[] args) {
String csvFile = "output.csv";
List<String[]> data = Arrays.asList(
new String[]{"Tên", "Tuổi", "Thành Phố", "Email"},
new String[]{"Nguyễn Văn A", "30", "Hà Nội", "a@example.com"},
new String[]{"Trần Thị B", "25", "Đà Nẵng", "b@example.com"}
);
try (BufferedWriter bw = new BufferedWriter(new FileWriter(csvFile))) {
for (String[] row : data) {
String csvLine = formatAsCSV(row);
bw.write(csvLine);
bw.newLine();
}
System.out.println("Tệp CSV đã được ghi thành công: " + csvFile);
} catch (IOException e) {
e.printStackTrace();
}
}
private static String formatAsCSV(String[] values) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < values.length; i++) {
String value = values[i];
if (value.contains(",") || value.contains("\"") || value.contains("\n")) {
sb.append('"').append(value.replace("\"", "\"\""));
sb.append('"');
} else {
sb.append(value);
}
if (i < values.length - 1) {
sb.append(',');
}
}
return sb.toString();
}
}
2. Sử Dụng OpenCSV
Cài Đặt OpenCSV
Để sử dụng OpenCSV, bạn cần thêm phụ thuộc vào dự án của mình:
Maven:
xml
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.7.1</version>
</dependency>
Gradle:
groovy
implementation 'com.opencsv:opencsv:5.7.1'
Đọc Tệp CSV
Sử dụng OpenCSV để đọc tệp CSV dễ dàng hơn:
java
import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
public class DocCSVOpenCSV {
public static void main(String[] args) {
String csvFile = "data.csv";
try (CSVReader reader = new CSVReaderBuilder(new FileReader(csvFile)).build()) {
List<String[]> allData = reader.readAll();
for (String[] row : allData) {
System.out.println(String.join(" | ", row));
}
System.out.println("Tổng số bản ghi: " + allData.size());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Ghi Tệp CSV
Ghi tệp CSV với OpenCSV cũng dễ dàng:
java
import com.opencsv.CSVWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class GhiCSVOpenCSV {
public static void main(String[] args) {
String csvFile = "output.csv";
List<String[]> data = Arrays.asList(
new String[]{"Tên", "Tuổi", "Thành Phố", "Email"},
new String[]{"Nguyễn Văn A", "30", "Hà Nội", "a@example.com"},
new String[]{"Trần Thị B", "25", "Đà Nẵng", "b@example.com"}
);
try (CSVWriter writer = new CSVWriter(new FileWriter(csvFile))) {
writer.writeAll(data);
System.out.println("Tệp CSV đã được ghi thành công: " + csvFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Ánh Xạ CSV tới Đối Tượng Java
OpenCSV cho phép bạn ánh xạ trực tiếp dữ liệu vào các đối tượng Java:
java
import com.opencsv.bean.CsvToBean;
import com.opencsv.bean.CsvToBeanBuilder;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
class Nguoi {
private String ten;
private int tuoi;
private String thanhPho;
private String email;
public Nguoi() {}
public Nguoi(String ten, int tuoi, String thanhPho, String email) {
this.ten = ten;
this.tuoi = tuoi;
this.thanhPho = thanhPho;
this.email = email;
}
// Getter và Setter
public String getTen() { return ten; }
public void setTen(String ten) { this.ten = ten; }
public int getTuoi() { return tuoi; }
public void setTuoi(int tuoi) { this.tuoi = tuoi; }
public String getThanhPho() { return thanhPho; }
public void setThanhPho(String thanhPho) { this.thanhPho = thanhPho; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
@Override
public String toString() {
return "Nguoi{ten='" + ten + "', tuoi=" + tuoi + ", thanhPho='" + thanhPho + "', email='" + email + "'}";
}
}
public class OpenCSVBeanExample {
public static void main(String[] args) {
String csvFile = "people.csv";
try (FileReader reader = new FileReader(csvFile)) {
CsvToBean<Nguoi> csvToBean = new CsvToBeanBuilder<Nguoi>(reader).build();
List<Nguoi> nguoiList = csvToBean.parse();
for (Nguoi nguoi : nguoiList) {
System.out.println(nguoi);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. So Sánh: Raw Java vs OpenCSV
| Tiêu chí | Java Thuần | OpenCSV |
|---|---|---|
| Độ phức tạp | Cao | Thấp |
| Kiểm soát | Cao | Thấp |
| Thư viện | Không có | Có |
| Xử lý lỗi | Phải tự xử lý | Tự động |
| Hỗ trợ ánh xạ | Không có | Có |
4. Thực Hành Tốt Nhất
- Luôn xử lý ngoại lệ - Tệp CSV có thể gặp nhiều vấn đề định dạng.
- Sử dụng try-with-resources để đảm bảo tệp được đóng đúng cách.
- Xác thực dữ liệu - Kiểm tra các giá trị null và kiểu dữ liệu.
- Xem xét mã hóa tệp - Chỉ định UTF-8 nếu làm việc với ký tự quốc tế.
- Sử dụng OpenCSV cho mã sản xuất - Nó xử lý các trường hợp biên tốt hơn mã tùy chỉnh.
- Với tệp lớn, đọc từng dòng thay vì tải toàn bộ tệp vào bộ nhớ.
5. Mẹo Hiệu Suất
- Sử dụng bộ đệm: Khi đọc hoặc ghi tệp lớn, sử dụng
BufferedReadervàBufferedWriterđể tăng tốc độ. - Tối ưu hóa việc phân tích: Nếu có nhiều trường hợp đặc biệt, hãy viết một bộ phân tích tùy chỉnh.
6. Khắc Phục Sự Cố
- Không tìm thấy tệp: Kiểm tra đường dẫn tệp có chính xác không.
- Dữ liệu không được phân tách đúng: Kiểm tra dấu phân cách trong tệp CSV.
- Ngoại lệ IO: Đảm bảo tệp không bị khóa hoặc đang được sử dụng bởi chương trình khác.
Kết Luận
Việc xử lý tệp CSV trong Java có thể được thực hiện bằng nhiều cách khác nhau, từ việc sử dụng Java thuần đến việc áp dụng thư viện OpenCSV. Mỗi phương pháp đều có những ưu và nhược điểm riêng, và tùy thuộc vào nhu cầu thực tế của bạn mà lựa chọn phương pháp phù hợp. Hãy thử nghiệm và tìm ra cách tốt nhất cho dự án của bạn!
Hãy bắt đầu làm việc với CSV trong Java ngay hôm nay!