Linux环境下C语言读取文件并操作数据库的实现指南

admin
本文介绍Linux环境下C语言实现文件读取与数据库操作的核心方法,通过fopen、fread等函数逐行读取文件内容,利用libmysql库连接MySQL数据库,构建SQL语句执行数据插入或更新操作,重点阐述文件流处理、数据库连接管理、事务控制及错误处理机制,确保数据读写高效可靠,适用于日志分析、数据迁移等场景,提供完整的代码实现思路与注意事项。

在Linux系统开发中,经常需要处理“读取文件数据并存储到数据库”的场景,例如日志分析、数据导入、配置处理等,本文将详细介绍如何使用C语言在Linux环境下逐行读取文件内容,并将解析后的数据存入数据库(以SQLite为例,兼顾MySQL的适配思路),涵盖环境准备、核心代码实现及注意事项。

环境准备

开发环境

  • Linux系统(如Ubuntu、CentOS等)
  • C编译器(GCC)
  • 数据库及开发库:
    • SQLite:轻量级嵌入式数据库,无需额外服务,适合示例场景,安装sqlite3库及开发包:
      sudo apt-get install sqlite3 libsqlite3-dev  # Ubuntu/Debian
      sudo yum install sqlite-devel                # CentOS/RHEL
    • MySQL(可选):若需使用MySQL,需安装libmysqlclient开发包:
      sudo apt-get install libmysqlclient-dev

文件与数据库准备

  • 示例文件data.txt(每行一条记录,用逗号分隔字段):
    1,zhangsan,25,beijing
    2,lisi,30,shanghai
    3,wangwu,28,guangzhou
  • 创建SQLite数据库及表(若使用MySQL,需提前创建数据库和表):
    sqlite3 test.db
    CREATE TABLE users (id INT, name TEXT, age INT, city TEXT);

核心实现步骤

逐行读取文件内容

在Linux中,C语言读取文件常用fopen+fgets组合,或更灵活的getline(动态分配内存,适合长行),这里以fgets为例(需处理缓冲区限制),辅以getline作为补充。

(1)使用fgets逐行读取

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE_LEN 1024  // 单行最大长度
void read_file_with_fgets(const char *filename) {
    FILE *file = fopen(filename, "r");
    if (!file) {
        perror("Failed to open file");
        return;
    }
    char line[MAX_LINE_LEN];
    while (fgets(line, MAX_LINE_LEN, file)) {
        // 去除行尾换行符(fgets会保留换行符)
        line[strcspn(line, "\n")] = '\0';
        printf("Read line: %s\n", line);  // 示例:打印读取的行
        // 后续解析行数据并插入数据库
    }
    fclose(file);
}

(2)使用getline(动态分配,推荐)

getline是POSIX标准函数,能自动分配内存处理任意长度行,需包含<stdio.h><unistd.h>(Linux环境下):

Linux环境下C语言读取文件并操作数据库的实现指南

void read_file_with_getline(const char *filename) {
    FILE *file = fopen(filename, "r");
    if (!file) {
        perror("Failed to open file");
        return;
    }
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    while ((read = getline(&line, &len, file)) != -1) {
        // 去除换行符(getline会保留换行符)
        if (line[read - 1] == '\n') {
            line[read - 1] = '\0';
        }
        printf("Read line: %s\n", line);  // 示例:打印读取的行
        // 后续解析行数据并插入数据库
    }
    free(line);  // 释放getline分配的内存
    fclose(file);
}

注意getline在较老的环境(如Ubuntu 16.04之前)可能需要手动链接-lutil,现代Linux系统通常已内置支持。

数据库操作(以SQLite为例)

(1)SQLite基本流程

  • 初始化数据库连接(sqlite3_open
  • 准备SQL语句(sqlite3_prepare_v2
  • 绑定参数(sqlite3_bind_*,防止SQL注入)
  • 执行语句(sqlite3_step
  • 释放资源(sqlite3_finalize, sqlite3_close

(2)封装数据库操作函数

#include <sqlite3.h>
// 插入数据到SQLite数据库
int insert_into_sqlite(sqlite3 *db, const char *id, const char *name, const char *age, const char *city) {
    char *sql = NULL;
    char *errmsg = NULL;
    int ret;
    // 构造SQL语句(使用参数化查询防止注入)
    sql = sqlite3_mprintf("INSERT INTO users (id, name, age, city) VALUES (%Q, %Q, %Q, %Q);", 
                          id, name, age, city);
    if (!sql) {
        fprintf(stderr, "Failed to allocate SQL string\n");
        return -1;
    }
    // 执行SQL
    ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    if (ret != SQLITE_OK) {
        fprintf(stderr, "SQL error: %s\n", errmsg);
        sqlite3_free(errmsg);
        sqlite3_free(sql);
        return -1;
    }
    sqlite3_free(sql);
    return 0;
}

整合:文件读取与数据库插入

将文件读取与数据库操作结合,完整代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
#define MAX_LINE_LEN 1024
int insert_into_sqlite(sqlite3 *db, const char *id, const char *name, const char *age, const char *city);
void process_file_and_insert(const char *filename, sqlite3 *db);
int main() {
    sqlite3 *db;
    const char *db_name = "test.db";
    // 1. 打开数据库
    if (sqlite3_open(db_name, &db) != SQLITE_OK) {
        fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
        return 1;
    }
    printf("Database opened successfully.\n");
    // 2. 处理文件并插入数据
    process_file_and_insert("data.txt", db);
    // 3. 关闭数据库
文章版权声明:除非注明,否则均为xmsdn原创文章,转载或复制请以超链接形式并注明出处。

取消
微信二维码
微信二维码
支付宝二维码