文件对比工具应用


欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net

适配的第三方库地址:

  • file_selector: https://pub.dev/packages/file_selector
  • cross_file: https://pub.dev/packages/cross_file
  • animations: https://pub.dev/packages/animations
  • shared_preferences: https://pub.dev/packages/shared_preferences

一、项目概述

运行效果图

(此处添加运行效果图)
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

1.1 应用简介

文件对比工具是一款专业的文件内容对比应用,致力于帮助用户快速发现文件之间的差异。应用支持文件内容对比、差异高亮显示、对比历史记录、结果导出等功能,让文件对比变得简单高效。

应用以专业的靛蓝色为主色调,象征精准与专业。涵盖对比页面、历史记录、设置中心三大模块。用户可以进行文本对比、查看差异统计、管理对比历史,是开发者和文档编辑者的得力助手。

1.2 核心功能

功能模块 功能描述 实现方式
文件对比 对比两个文件内容差异 LCS算法
差异高亮 高亮显示新增、删除、修改内容 颜色标记
对比统计 统计变更数量和相似度 数据分析
历史记录 保存对比历史记录 本地存储
结果导出 导出对比结果为文本或HTML 文件生成
搜索过滤 搜索和过滤对比内容 关键词匹配
行号显示 显示行号便于定位 行号列
交换文件 快速交换左右文件 数据交换

1.3 差异类型定义

序号 类型名称 Emoji 颜色 描述
1 新增 绿色 右侧新增的内容
2 删除 红色 左侧删除的内容
3 修改 📝 橙色 发生变化的内容
4 未变 灰色 未发生变化的内容

1.4 对比模式定义

序号 模式名称 图标 描述 特点
1 文本对比 📝 按文本内容对比 整体对比
2 行对比 📋 按行逐行对比 精确定位
3 单词对比 📄 按单词对比 细粒度对比

1.5 技术栈

技术领域 技术选型 版本要求
开发框架 Flutter >= 3.0.0
编程语言 Dart >= 2.17.0
设计规范 Material Design 3 -
文件选择 file_selector >= 1.0.0
文件操作 cross_file >= 1.0.0
动画效果 animations >= 2.0.0
历史存储 shared_preferences >= 2.0.0
目标平台 鸿蒙OS / Android / iOS API 21+

1.6 项目结构

lib/
└── main_file_compare.dart
    ├── FileCompareApp              # 应用入口
    ├── DiffType                    # 差异类型枚举
    ├── CompareMode                 # 对比模式枚举
    ├── DiffLine                    # 差异行模型
    ├── CompareResult               # 对比结果模型
    ├── CompareHistory              # 对比历史模型
    ├── FileCompareController       # 文件对比控制器
    ├── CompareHomePage             # 主页面(底部导航)
    ├── _buildComparePage           # 对比页
    ├── _buildHistoryPage           # 历史页
    ├── _buildSettingsPage          # 设置页
    └── _buildDiffLine              # 差异行组件

二、系统架构

2.1 整体架构图

Data Layer

Business Layer

Presentation Layer

主页面
CompareHomePage

对比页

历史页

设置页

统计摘要

模式选择

差异列表

历史列表

历史详情

显示设置

颜色设置

文件对比控制器
FileCompareController

LCS算法
LongestCommonSubsequence

导出管理器
ExportManager

DiffLine
差异行

CompareResult
对比结果

CompareHistory
对比历史

2.2 类图设计

generates

creates

stores

has

contains

FileCompareApp

+Widget build()

«enumeration»

DiffType

+String label

+Color color

+IconData icon

+added()

+removed()

+modified()

+unchanged()

«enumeration»

CompareMode

+String label

+IconData icon

+text()

+line()

+word()

DiffLine

+int leftLineNumber

+int? rightLineNumber

+String leftContent

+String? rightContent

+DiffType type

+int changeIndex

CompareResult

+String leftFileName

+String rightFileName

+DateTime compareTime

+List<DiffLine> diffLines

+int addedCount

+int removedCount

+int modifiedCount

+int unchangedCount

+int totalChanges

+double similarityPercent

CompareHistory

+String id

+String leftFileName

+String rightFileName

+DateTime compareTime

+int changeCount

+double similarityPercent

FileCompareController

-String _leftContent

-String _rightContent

-List<DiffLine> _diffLines

-List<CompareHistory> _history

+String leftContent

+String rightContent

+List<DiffLine> diffLines

+CompareResult? currentResult

+setLeftContent()

+setRightContent()

+compare()

+swapContents()

+exportAsText()

+exportAsHtml()

2.3 页面导航流程

对比

历史

设置

应用启动

主页面

底部导航

对比页

历史页

设置页

输入文件内容

执行对比

显示差异

查看统计

搜索过滤

导出结果

查看历史列表

点击历史项

修改显示设置

修改颜色设置

2.4 对比算法流程

差异生成器 LCS算法 控制器 用户 差异生成器 LCS算法 控制器 用户 输入左右文件内容 分割为行列表 计算最长公共子序列 构建DP表 回溯获取LCS 返回LCS结果 生成差异行 标记新增/删除/未变 返回差异列表 计算统计数据 显示对比结果

三、核心模块设计

3.1 数据模型设计

3.1.1 差异类型枚举 (DiffType)
enum DiffType {
  added(label: '新增', color: Color(0xFF4CAF50), icon: Icons.add),
  removed(label: '删除', color: Color(0xFFF44336), icon: Icons.remove),
  modified(label: '修改', color: Color(0xFFFF9800), icon: Icons.edit),
  unchanged(label: '未变', color: Color(0xFF9E9E9E), icon: Icons.remove);

  final String label;
  final Color color;
  final IconData icon;
  const DiffType({required this.label, required this.color, required this.icon});
}
3.1.2 差异行模型 (DiffLine)
class DiffLine {
  final int leftLineNumber;
  final int? rightLineNumber;
  final String leftContent;
  final String? rightContent;
  final DiffType type;
  final int changeIndex;

  const DiffLine({
    required this.leftLineNumber,
    this.rightLineNumber,
    required this.leftContent,
    this.rightContent,
    required this.type,
    required this.changeIndex,
  });
}
3.1.3 对比结果模型 (CompareResult)
class CompareResult {
  final String leftFileName;
  final String rightFileName;
  final DateTime compareTime;
  final List<DiffLine> diffLines;
  final int addedCount;
  final int removedCount;
  final int modifiedCount;
  final int unchangedCount;

  int get totalChanges => addedCount + removedCount + modifiedCount;
  double get similarityPercent {
    if (totalLines == 0) return 100;
    return (unchangedCount / totalLines) * 100;
  }
}
3.1.4 差异类型分布
60% 20% 12% 8% 差异类型分布示例 未变 新增 删除 修改

3.2 LCS算法设计

3.2.1 算法原理

最长公共子序列(LCS)算法是文件对比的核心:

渲染错误: Mermaid 渲染失败: Parse error on line 8: ... F[如果字符相同] --> G[dp[i][j] = dp[i-1][j-1 -----------------------^ Expecting 'SQE', 'DOUBLECIRCLEEND', 'PE', '-)', 'STADIUMEND', 'SUBROUTINEEND', 'PIPE', 'CYLINDEREND', 'DIAMOND_STOP', 'TAGEND', 'TRAPEND', 'INVTRAPEND', 'UNICODE_TEXT', 'TEXT', 'TAGSTART', got 'SQS'
3.2.2 算法实现
List<String> _computeLCS(List<String> left, List<String> right) {
  final m = left.length;
  final n = right.length;
  
  // 构建DP表
  final dp = List.generate(m + 1, (_) => List.filled(n + 1, 0));
  
  for (int i = 1; i <= m; i++) {
    for (int j = 1; j <= n; j++) {
      if (left[i - 1] == right[j - 1]) {
        dp[i][j] = dp[i - 1][j - 1] + 1;
      } else {
        dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
      }
    }
  }
  
  // 回溯获取LCS
  final lcs = <String>[];
  int i = m, j = n;
  while (i > 0 && j > 0) {
    if (left[i - 1] == right[j - 1]) {
      lcs.insert(0, left[i - 1]);
      i--;
      j--;
    } else if (dp[i - 1][j] > dp[i][j - 1]) {
      i--;
    } else {
      j--;
    }
  }
  
  return lcs;
}

3.3 页面结构设计

3.3.1 对比页结构

对比页

SliverAppBar

统计摘要

模式选择

过滤栏

差异列表

文件名显示

交换按钮

导出按钮

新增数

删除数

修改数

相似度

搜索框

仅显示变更

显示行号

3.3.2 差异行组件结构

差异行

左侧行号

右侧行号

前缀符号

内容区域

背景色

背景色

+/-/~符号

可选中文本

等宽字体

3.4 导出功能设计

文本

HTML

剪贴板

点击导出

选择格式

生成TXT

生成HTML

复制内容

纯文本格式

+/-前缀标记

带样式HTML

颜色高亮

行号显示

复制到系统剪贴板


四、UI设计规范

4.1 配色方案

应用以专业的靛蓝色为主色调,象征精准与专业:

颜色类型 色值 用途
主色 #3F51B5 (Indigo) 导航、主题元素
辅助色 #5C6BC0 渐变效果
第三色 #7986CB 卡片背景
强调色 #303F9F 按钮高亮
背景色 #FAFAFA 页面背景
卡片背景 #FFFFFF 信息卡片
新增色 #4CAF50 新增内容
删除色 #F44336 删除内容
修改色 #FF9800 修改内容

4.2 差异类型配色

类型 色值 背景色 视觉效果
新增 #4CAF50 #E8F5E9 绿色
删除 #F44336 #FFEBEE 红色
修改 #FF9800 #FFF3E0 橙色
未变 #9E9E9E 透明 灰色

4.3 字体规范

元素 字号 字重 颜色
页面标题 24px Bold 主色
文件名 16px Medium 白色
差异内容 13px Regular 差异类型色
行号 12px Regular 灰色
统计数字 24px Bold 主色

4.4 组件规范

4.4.1 差异行
┌─────────────────────────────────────┐
│  12  12  │ - │ import 'package:flutter/material.dart'; │
├─────────────────────────────────────┤
│  13      │ - │   title: 'Flutter Demo',               │
├─────────────────────────────────────┤
│      13  │ + │   title: 'Flutter App',                │
└─────────────────────────────────────┘
4.4.2 统计摘要
┌─────────────────────────────────────┐
│   ➕          ➖          📝         │
│   12         8           5          │
│  新增       删除        修改        │
│                                     │
│            85.5%                    │
│           相似度                    │
└─────────────────────────────────────┘
4.4.3 历史项
┌─────────────────────────────────────┐
│  ⚖️  main.dart ⇄ main_new.dart      │
│      25处变更  相似度 75.0%   2天前 │
└─────────────────────────────────────┘

五、核心功能实现

5.1 文件对比控制器实现

class FileCompareController extends ChangeNotifier {
  String _leftContent = '';
  String _rightContent = '';
  List<DiffLine> _diffLines = [];

  void compare() {
    final leftLines = _leftContent.split('\n');
    final rightLines = _rightContent.split('\n');
    
    _diffLines = _computeDiff(leftLines, rightLines);
    _addToHistory();
    notifyListeners();
  }

  List<DiffLine> _computeDiff(List<String> left, List<String> right) {
    final result = <DiffLine>[];
    final lcs = _computeLCS(left, right);
    // ... 差异计算逻辑
    return result;
  }
}

5.2 LCS算法实现

List<String> _computeLCS(List<String> left, List<String> right) {
  final m = left.length;
  final n = right.length;
  
  final dp = List.generate(m + 1, (_) => List.filled(n + 1, 0));
  
  for (int i = 1; i <= m; i++) {
    for (int j = 1; j <= n; j++) {
      if (left[i - 1] == right[j - 1]) {
        dp[i][j] = dp[i - 1][j - 1] + 1;
      } else {
        dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
      }
    }
  }
  
  // 回溯获取LCS
  final lcs = <String>[];
  int i = m, j = n;
  while (i > 0 && j > 0) {
    if (left[i - 1] == right[j - 1]) {
      lcs.insert(0, left[i - 1]);
      i--;
      j--;
    } else if (dp[i - 1][j] > dp[i][j - 1]) {
      i--;
    } else {
      j--;
    }
  }
  
  return lcs;
}

5.3 导出功能实现

String exportAsText() {
  final buffer = StringBuffer();
  buffer.writeln('文件对比结果');
  buffer.writeln('左文件: $_leftFileName');
  buffer.writeln('右文件: $_rightFileName');
  
  for (var line in _diffLines) {
    final prefix = switch (line.type) {
      DiffType.added => '+ ',
      DiffType.removed => '- ',
      DiffType.modified => '~ ',
      DiffType.unchanged => '  ',
    };
    buffer.writeln('$prefix${line.leftContent}');
  }
  
  return buffer.toString();
}

String exportAsHtml() {
  final buffer = StringBuffer();
  buffer.writeln('<!DOCTYPE html>');
  buffer.writeln('<html><head><meta charset="UTF-8">');
  buffer.writeln('<style>');
  buffer.writeln('.added { background-color: #e8f5e9; }');
  buffer.writeln('.removed { background-color: #ffebee; }');
  buffer.writeln('.modified { background-color: #fff3e0; }');
  buffer.writeln('</style></head><body>');
  // ... HTML内容生成
  return buffer.toString();
}

5.4 搜索过滤实现

void setSearchQuery(String query) {
  _searchQuery = query;
  notifyListeners();
}

// 在构建列表时过滤
if (_controller.searchQuery.isNotEmpty) {
  final content = line.type == DiffType.added 
    ? line.rightContent ?? '' 
    : line.leftContent;
  if (!content.toLowerCase().contains(_controller.searchQuery.toLowerCase())) {
    return null;
  }
}

六、交互设计

6.1 对比流程

差异列表 控制器 对比页 用户 差异列表 控制器 对比页 用户 输入/粘贴文件内容 setLeftContent/setRightContent 点击对比按钮 compare() 计算LCS 生成差异行 通知更新 显示差异 高亮显示差异

6.2 导出流程

文本

HTML

剪贴板

点击导出按钮

显示导出选项

选择导出格式

生成TXT内容

生成HTML内容

复制到剪贴板

显示预览

显示成功提示

用户复制/保存

6.3 搜索过滤流程

清除

输入搜索词

过滤差异列表

显示匹配项

清空搜索词

显示全部


七、扩展功能规划

7.1 后续版本规划

2024-01-07 2024-01-14 2024-01-21 2024-01-28 2024-02-04 2024-02-11 2024-02-18 2024-02-25 2024-03-03 2024-03-10 2024-03-17 2024-03-24 2024-03-31 基础UI框架 LCS算法实现 导出功能 文件选择集成 动画效果 历史持久化 三方对比 图片对比 云端同步 V1.0 基础版本 V1.1 增强版本 V1.2 进阶版本 文件对比工具开发计划

7.2 功能扩展建议

7.2.1 文件选择

文件功能:

  • 本地文件选择
  • 拖拽文件上传
  • URL文件加载
  • 剪贴板粘贴
7.2.2 高级对比

对比功能:

  • 三方文件对比
  • 文件夹对比
  • 图片对比
  • 二进制文件对比
7.2.3 协作功能

协作功能:

  • 分享对比链接
  • 在线协作标注
  • 评论功能
  • 版本历史

八、注意事项

8.1 开发注意事项

  1. 性能优化:大文件对比时注意性能优化

  2. 内存管理:避免加载过大文件导致内存溢出

  3. 编码处理:正确处理不同编码的文件

  4. 差异算法:优化LCS算法提高效率

  5. 用户体验:提供清晰的差异展示

8.2 常见问题

问题 原因 解决方案
对比慢 文件过大 分块处理
内存溢出 文件太大 限制文件大小
编码乱码 编码不一致 自动检测编码
差异不准 算法问题 优化LCS实现
导出失败 内容过长 分段导出

8.3 使用技巧

📄 文件对比工具使用技巧 📄

对比技巧

  • 选择合适的对比模式
  • 使用搜索快速定位
  • 开启仅显示变更模式
  • 利用行号精确定位

导出技巧

  • HTML格式保留样式
  • 文本格式便于分享
  • 复制到剪贴板快速粘贴
  • 保存对比结果备查

效率提升

  • 使用交换功能快速切换
  • 定期清理历史记录
  • 设置常用显示选项
  • 熟悉快捷键操作

九、鸿蒙适配说明

9.1 权限配置

ohos/entry/src/main/module.json5 中添加权限:

{
  "module": {
    "requestPermissions": [
      {"name": "ohos.permission.INTERNET"},
      {"name": "ohos.permission.READ_MEDIA"},
      {"name": "ohos.permission.WRITE_MEDIA"}
    ]
  }
}

9.2 第三方库适配状态

第三方库 适配状态 说明
file_selector ✅ 已适配 文件选择
cross_file ✅ 已适配 文件操作
animations ✅ 已适配 动画效果
shared_preferences ✅ 已适配 历史存储

9.3 运行命令

# 查看可用设备
flutter devices

# 运行到Web服务器
flutter run -d web-server -t lib/main_file_compare.dart --web-port 8150

# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 -t lib/main_file_compare.dart

# 代码分析
flutter analyze lib/main_file_compare.dart

十、总结

文件对比工具应用为用户提供了一套专业的文件内容对比解决方案。应用支持文件内容对比、差异高亮显示、对比历史记录、结果导出等功能,让文件对比变得简单高效。

核心功能涵盖文件对比、差异高亮、对比统计、历史记录、结果导出、搜索过滤、行号显示、交换文件八大模块。用户可以进行文本对比、查看差异统计、管理对比历史,是开发者和文档编辑者的得力助手。

应用采用 Material Design 3 设计规范,以专业的靛蓝色为主色调,象征精准与专业。通过本应用,希望能够帮助用户快速发现文件差异,提高工作效率,让文件对比变得轻松愉快。

文件对比工具——精准对比,高效工作


Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐