本文介绍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
- SQLite:轻量级嵌入式数据库,无需额外服务,适合示例场景,安装
文件与数据库准备
- 示例文件
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环境下):

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原创文章,转载或复制请以超链接形式并注明出处。

