You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lxCameraApi/CHANGELOG_PATH_UPDATE.md

9.6 KiB

路径格式更新说明

更新日期

2025-03-25

更新内容

1. 文件保存路径格式变更

原路径格式

basePath/SN_type_timestamp.ext

示例:

D:/output/192.168.1.100_pointcloud_20250325_143022.pcd
D:/output/192.168.1.100_rgb_20250325_143022.png

新路径格式

basePath/日期/类型/SN_type_timestamp.ext

示例:

D:/output/20250325/pointCloud/192.168.1.100_pointcloud_20250325_143022.pcd
D:/output/20250325/rgb/192.168.1.100_rgb_20250325_143022.png

2. 目录结构变化

原结构

D:/output/
├── 192.168.1.100_pointcloud_20250325_143022.pcd
├── 192.168.1.100_rgb_20250325_143022.png
├── 192.168.1.101_pointcloud_20250325_143023.pcd
└── ...

新结构

D:/output/
├── 20250325/
│   ├── amplitude/
│   │   ├── 192.168.1.100_amplitude_20250325_143022.png
│   │   └── ...
│   ├── rgb/
│   │   ├── 192.168.1.100_rgb_20250325_143022.png
│   │   └── ...
│   ├── depth/
│   │   ├── 192.168.1.100_depth_20250325_143022.png
│   │   └── ...
│   ├── depthColor/
│   │   ├── 192.168.1.100_depth_color_20250325_143022.png
│   │   └── ...
│   └── pointCloud/
│       ├── 192.168.1.100_pointcloud_20250325_143022.pcd
│       └── ...
├── 20250326/
│   └── ...
└── 20250327/
    └── ...

3. 路径组成部分详解

组成部分 说明 示例值
basePath 基础保存路径 D:/output
日期 拍摄日期yyyyMMdd 20250325
类型 文件类型文件夹 amplitudergbdepthdepthColorpointCloud
SN 相机序列号 192.168.1.100
type 文件类型(文件名中) amplitudergbdepthdepthColorpointcloud
timestamp 时间戳yyyyMMdd_HHmmss 20250325_143022
ext 文件扩展名 .png.pcd

修改的文件

1. LxCameraServiceImpl.java

  • 添加日期生成逻辑
  • 修改所有文件保存路径,增加日期和类型文件夹
  • 更新日志信息

修改位置:

  • 第259行添加日期生成
  • 第291-350行修改所有保存路径

2. LX_CAMERA_USAGE.md

  • 添加路径格式说明
  • 更新目录树示例
  • 更新API响应示例

3. LxCameraServiceExample.java

  • 更新示例注释
  • 修正示例4的裁剪路径逻辑

4. 新增文件

  • PATH_STRUCTURE.md - 详细的路径结构说明文档

优势

1. 更好的数据组织

  • 按日期分类:便于按天管理和查找数据
  • 按类型分类:便于按类型批量处理
  • 结构清晰:一目了然,易于维护

2. 更高效的数据管理

  • 快速定位:可以快速找到某天某类型的所有数据
  • 批量操作:便于批量删除、备份、归档某天的数据
  • 空间管理:可以按天统计磁盘占用

3. 更好的可扩展性

  • 自动归档:可以轻松实现按天、月、年归档
  • 分布式存储:可以将不同日期的数据存储在不同磁盘
  • 数据清理:便于实现定期清理旧数据的策略

兼容性说明

向后兼容

  • API接口保持不变
  • 参数格式保持不变
  • 返回值结构保持不变

变更影响

  • ⚠️ 调用方需要适配新的返回路径格式
  • ⚠️ 现有的路径处理逻辑需要更新

迁移指南

1. 更新调用代码

如果代码中硬编码了路径格式,需要更新:

旧代码:

String pointCloudPath = basePath + "/" + cameraSn + "_pointcloud_" + timestamp + ".pcd";

新代码:

CaptureResult result = lxCameraService.capture(cameraSn, basePath);
String pointCloudPath = result.getFilePath("pointCloud");
// 路径格式: basePath/20250325/pointCloud/192.168.1.100_pointcloud_20250325_143022.pcd

2. 处理历史数据

如果需要将旧格式数据迁移到新格式:

import java.nio.file.*;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class DataMigration {

    // 旧路径: basePath/SN_type_timestamp.ext
    // 新路径: basePath/日期/类型/SN_type_timestamp.ext

    public static void migrateOldData(String basePath) throws IOException {
        Path baseDir = Paths.get(basePath);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss");

        Files.list(baseDir)
            .filter(path -> !Files.isDirectory(path))
            .forEach(file -> {
                String filename = file.getFileName().toString();

                // 解析文件名: 192.168.1.100_pointcloud_20250325_143022.pcd
                String[] parts = filename.split("_");
                if (parts.length >= 3) {
                    String sn = parts[0];
                    String type = parts[1];
                    String timestamp = parts[2].split("\\.")[0];

                    // 提取日期
                    String date = timestamp.substring(0, 8);

                    // 构建新路径
                    Path targetDir = baseDir.resolve(date).resolve(type);
                    try {
                        Files.createDirectories(targetDir);
                        Path targetFile = targetDir.resolve(filename);
                        Files.move(file, targetFile);
                        System.out.println("迁移: " + file + " -> " + targetFile);
                    } catch (IOException e) {
                        System.err.println("迁移失败: " + filename);
                    }
                }
            });
    }

    public static void main(String[] args) throws IOException {
        migrateOldData("D:/output");
    }
}

3. 更新数据清理逻辑

如果实现了定期清理旧数据的逻辑,需要适配新结构:

import java.io.File;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class DataCleaner {

    /**
     * 删除指定天数之前的所有数据
     */
    public static void cleanOldData(String basePath, int daysToKeep) {
        LocalDate cutoffDate = LocalDate.now().minusDays(daysToKeep);
        File baseDir = new File(basePath);

        File[] dateDirs = baseDir.listFiles(File::isDirectory);
        if (dateDirs == null) return;

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");

        for (File dateDir : dateDirs) {
            try {
                LocalDate dirDate = LocalDate.parse(dateDir.getName(), formatter);
                if (dirDate.isBefore(cutoffDate)) {
                    deleteDirectory(dateDir);
                    System.out.println("已删除: " + dateDir.getAbsolutePath());
                }
            } catch (Exception e) {
                System.err.println("无法解析日期: " + dateDir.getName());
            }
        }
    }

    private static void deleteDirectory(File dir) {
        File[] files = dir.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    deleteDirectory(file);
                } else {
                    file.delete();
                }
            }
        }
        dir.delete();
    }

    public static void main(String[] args) {
        // 保留30天的数据
        cleanOldData("D:/output", 30);
    }
}

测试建议

1. 单元测试

@Test
public void testPathFormat() {
    String cameraSn = "192.168.1.100";
    String basePath = "D:/output";

    CaptureConfig config = CaptureConfig.createDefault();
    CaptureResult result = lxCameraService.capture(cameraSn, basePath, config);

    assertTrue(result.isSuccess());

    String pointCloudPath = result.getFilePath("pointCloud");
    assertTrue(pointCloudPath.contains("/20"));
    assertTrue(pointCloudPath.contains("/pointCloud/"));
    assertTrue(pointCloudPath.contains(cameraSn));
    assertTrue(pointCloudPath.endsWith(".pcd"));
}

2. 集成测试

@Test
public void testDirectoryStructure() {
    String basePath = "D:/test_output";

    CaptureConfig config = CaptureConfig.createFullCapture();
    CaptureResult result = lxCameraService.capture("192.168.1.100", basePath, config);

    assertTrue(result.isSuccess());

    // 验证目录结构
    Files.walk(Paths.get(basePath))
        .filter(Files::isDirectory)
        .forEach(dir -> {
            String dirName = dir.getFileName().toString();
            assertTrue(dirName.matches("\\d{8}") ||  // 日期
                      dirName.equals("amplitude") ||
                      dirName.equals("rgb") ||
                      dirName.equals("depth") ||
                      dirName.equals("depthColor") ||
                      dirName.equals("pointCloud"));
        });
}

注意事项

  1. 自动创建目录:系统会自动创建所需的目录结构
  2. 路径长度限制Windows路径长度限制为260字符注意basePath不要过长
  3. 磁盘权限确保程序对basePath有读写权限
  4. 并发安全:多个相机同时拍照时,路径结构支持并发
  5. 时区问题:使用系统时区,注意时间的一致性

后续优化建议

  1. 配置化:将路径格式提取到配置文件,便于修改
  2. 自定义模板:支持用户自定义路径模板
  3. 文件压缩:自动压缩旧的点云数据
  4. 分布式存储:支持将不同日期数据存储到不同磁盘
  5. 自动归档:按月自动归档数据

相关文档

  • PATH_STRUCTURE.md - 详细的路径结构说明
  • LX_CAMERA_USAGE.md - 使用说明文档
  • CHANGELOG.md - 变更日志