0
0
Lập trình
TT

Hướng Dẫn Xử Lý Tệp CSV Toàn Diện trong Java

Đăng vào 1 tháng trước

• 11 phút đọc

Chủ đề:

#csv#java#opencsv

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

  1. Sử Dụng Java Thuần
  2. Sử Dụng OpenCSV
  3. So Sánh: Java Thuần vs OpenCSV
  4. Thực Hành Tốt Nhất
  5. Mẹo Hiệu Suất
  6. 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 Copy
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 Copy
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 Copy
<dependency>
    <groupId>com.opencsv</groupId>
    <artifactId>opencsv</artifactId>
    <version>5.7.1</version>
</dependency>

Gradle:

groovy Copy
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 Copy
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 Copy
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 Copy
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ó
Xử lý lỗi Phải tự xử lý Tự động
Hỗ trợ ánh xạ Không có

4. Thực Hành Tốt Nhất

  1. Luôn xử lý ngoại lệ - Tệp CSV có thể gặp nhiều vấn đề định dạng.
  2. Sử dụng try-with-resources để đảm bảo tệp được đóng đúng cách.
  3. Xác thực dữ liệu - Kiểm tra các giá trị null và kiểu dữ liệu.
  4. 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ế.
  5. 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.
  6. 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 BufferedReaderBufferedWriter để 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!

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào