当前位置: 首页 > article >正文

NetBeans 8.2 开发 CIFLog3.5 - 数据导入导出案例

NetBeans 8.2 开发 CIFLog3.5 - 数据导入导出案例

  • NetBeans 8.2 开发 CIFLog3.5 - 数据导入导出案例
    • NetBeans 8.2 开发 CIFLog3.5 - 数据导入导出案例
      • 开发数据导入导出模块
        • (1)新建模块
        • (2)添加模块依赖关系
        • (3)新建Java类
        • (4)介绍数据导入流程
        • (5)编写入口类代码
        • (6)编写导入功能代码
        • (7)完成导入功能
        • (8)数据导出功能实现与完成

CIFLog测井平台由中国石油勘探开发研究院李宁团队研发,是国内行业领先的测井软件,其功能强大,在教学和科研中被广泛使用。目前版本:3.5(博主已知是这个),石油科研院所和高校可申请免费使用。

NetBeans 8.2 开发 CIFLog3.5 - 数据导入导出案例

参考书籍《CIFLog测井软件平台用户应用系统开发》
在这里插入图片描述

NetBeans 8.2 开发 CIFLog3.5 - 数据导入导出案例

本博客内容上接 NetBeans 8.2 开发 CIFLog3.5 - 数据访问案例

没有安装CIFLog的小伙伴可以参考 NetBeans 8.2 开发 CIFLog3.5 - 创建WelcomeDemo

开发数据导入导出模块

(1)新建模块

首先打开netbeans 8.2
在这里插入图片描述
在这里插入图片描述

新建模块
在这里插入图片描述

选择 NetBeans 模块,然后选择 NetBeans 模块

在这里插入图片描述

给项目命名,DataImportDemo
在这里插入图片描述

设置代码名称基

cif.demo.dataimport

在这里插入图片描述

点击 完成 ,成功创建模块

在这里插入图片描述

(2)添加模块依赖关系

模块 右键,选择 属性

在这里插入图片描述
点击左边的 ,然后点 添加依赖

在这里插入图片描述
添加如下的依赖

在这里插入图片描述

(3)新建Java类

进入 源包,对刚才创建的包右键,选择Java类

在这里插入图片描述

类名为 Text1DConversion

在这里插入图片描述

继承 ConversionBase

在这里插入图片描述

类名 按住 alt+回车,点击实现全部抽象方法

在这里插入图片描述

(4)介绍数据导入流程

以导入 .txt 文本文件为例子

打开CIFlog选择数据后,会展示出如下界面,点击红色的图案,进入数据格式转换界面
在这里插入图片描述
左下角部分会展示出许多数据格式转换的模块,这些都是已经提供好的,可以拿来直接用

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

点击导入数据按钮,可以选择一个数据导入,然后点击转换,根据已有的模块,可以把数据转换成我们需要的类型的数据

左下角的这些模块都已jar的方式放到指定的目录下,这样CIFLog会自动识别并导入模块,格式转换模块的路径在安装目录下的 conversionJars 文件夹中

在这里插入图片描述
在实现我们自己的数据转换模块后,把jar文件放到这个路径下,就可以使用了,接下来就开始编写代码

(5)编写入口类代码

首先编写入口类,右键 源包,点击新建 Java 包

在这里插入图片描述
创建名为 conversion 的包

在这里插入图片描述

conversion 包右键,创建 Java类

在这里插入图片描述
创建名为 ConversionEntry 的Java类

在这里插入图片描述

需要实现 ConversionEntryInterface 接口,并重写其中的方法

public class ConversionEntry implements ConversionEntryInterface {
    

    @Override
    public ConversionBase getConversionInstance() {
        return new Text1DConversion();
    }
    
}

在这里插入图片描述

(6)编写导入功能代码

接下来编写 Text1DConversion 类中的代码

这里有一个代码编写顺序,不按顺序会出现问题。

  1. 实现getFormatTypeString方法
  2. 实现getFormatExtension方法
  3. 实现isThisFormat方法
  4. 实现**fileScan()**方法

首先,当我们点击这个图标后,CIFLog会自动识别conversionJars文件夹下的jar包,根据左括号后面的字符串字母顺序进行排序,因此可以看到A开头的模块在前,Z开头的在最后
在这里插入图片描述
在这里插入图片描述
这个左下角展示的文字,由getFormatTypeString方法的返回值来设置

所以,我们首先要实现这个方法
在这里插入图片描述

否则在点击图标的时候会报错

在这里插入图片描述

根据详细信息的错误提示,可以看到是这个方法内部报错了
在这里插入图片描述
所以第一步要实现这个方法

但是,实现这个方法有规则,必须包含 ,左括号

如果不包含,按照如下写法,就会报错误

在这里插入图片描述

在这里插入图片描述

如果打开界面时,出现的下面这个错误,这个错误是因为没有写入口类导致的,需要写 ConversionEntry

在这里插入图片描述
那么数组越界错误是怎么回事,为什么会出现呢?

我们查看详细情况,看到里面有个compare方法,接下来就要去这个方法,看看源码是怎么实现的

在这里插入图片描述

进入 ConversionPanel 类,找到 compare 方法

在这里插入图片描述
可以看到这里有具体的实现代码,不过不是Java的字节码,下面逐一解析

  1. aload_1; 加载本地变量 1(ConversionBase 对象)
  2. invokevirtual cif/formatconversion/ConversionBase.getFormatTypeString:()Ljava/lang/String; 对象调用obj1.getFormatTypeString()
  3. ldc “\(”; 加载常量字符串 “\(”
  4. invokevirtual java/lang/String.split:(Ljava/lang/String;)[Ljava/lang/String; 使用 split(“\(”) 方法拆分字符串,以 左括号进行分割,返回一个 String 数组。
  5. iconst_1 加载常数 1
  6. aaload 取数组索引 1 处的字符串,即取 split(“\(”) 结果的第 2 个元素
  7. aload_2 加载本地变量 2(另一个 ConversionBase 对象)
  8. invokevirtual cif/formatconversion/ConversionBase.getFormatTypeString:()Ljava/lang/String; 对象调用obj2.getFormatTypeString()
  9. ldc “\(” 加载常量字符串 “\(”
  10. invokevirtual java/lang/String.split:(Ljava/lang/String;)[Ljava/lang/String; 使用 split(“\(”) 方法拆分字符串
  11. iconst_1 加载常数 1
  12. aaload 取数组索引 1 处的字符串,即取 split(“\(”) 结果的第 2 个元素
  13. invokevirtual java/lang/String.compareTo:(Ljava/lang/String;)I 调用 compareTo() 比较两个字符串
  14. ireturn 返回 compareTo() 的结果

最后返回的是左括号右边字符串的比较结果,因此最后以左括号右边的字符串进行排序,可以看到下图名称的排序顺序,以左括号右边的字符串排序的

在这里插入图片描述
由于字节码中出现了这段代码

iconst_1 加载常数 1
aaload 取数组索引 1 处的字符串,即取 split(“\(”) 结果的第 2 个元素

也就是说如果不包含左括号,字符串分割的结果中,就不会出现第二个元素,如果此时访问索引为1处的元素,就会抛出ArrayIndexOutOfBoundsException的异常

因此我们要修改代码,修改为带有左括号的

@Override
public String getFormatTypeString() {
    return "Test1DConversion(Test)";
}

在这里插入图片描述
接下来实现getFormatExtension方法,书上介绍:该方法获得数据格式后缀字符串,如果是该格式支持多个字符串后缀,使用“,”分割

我们这里处理 .txt 文本文件,所以我们直接返回"txt"就可以了

在这里插入图片描述
如果不实现,就会出现下面的问题,CIFLog不知道你要处理哪种格式的数据,因此左下角不会出现我们编写的模块

在这里插入图片描述

接下来,第三步,实现isThisFormat方法

public boolean isThisFormat(String string) throws Exception {
    String extension = ConversionPathUtil.getExtension(string);
    return extension.compareToIgnoreCase("TXT") == 0;
}

在这里插入图片描述

该方法的作用是判断导入的文件是否具有 .txt 后缀(不区分大小写)。如果是 .txt 文件,方法返回 true;否则返回 false。

如果不实现这个方法,当你选择了一个 .txt 文件后,右边会出现the specified file is an unrecognized format.

在这里插入图片描述

接下来,第四步,实现 fileScan() 方法

public StringBuffer fileScan() {
    StringBuffer strBuffer = new StringBuffer("123");
    String s; // Read the string formed by each line of content in the file.
    int dataRowNum = 0;
    try {
        BufferedReader in = new BufferedReader(
            new FileReader(new File(this.selectedFilePath)));
        while ((s = in.readLine()) != null){
            if (dataRowNum == 0) {
                this.wellName = s.split("=")[1];
            } else if (dataRowNum == 1) {
                this.curDepth = this.startDepth = Double.parseDouble(s.split("=")[1].trim());
            } else if (dataRowNum == 2) {
                this.endDepth = Double.parseDouble(s.split("=")[1].trim());
            } else if (dataRowNum == 3) {
                this.depthLev = Double.parseDouble(s.split("=")[1].trim());
            } else if (dataRowNum == 4) {
                this.curveNames = Optional.of(s.replaceFirst("CURNAMES", ""))
                       .map(str -> str.split(","))
                       .map(Arrays::stream)  
                       .map(stream -> stream.map(String::trim)) 
                       .map(stream -> stream.toArray(String[]::new))
                       .orElse(new String[]{});
            }
            if (dataRowNum >= this.MAX_DISPLAY_ROW) {
                strBuffer.append("There is a lot of displayed text. Currently, only the first ")
                        .append(this.MAX_DISPLAY_ROW).append(" lines are shown.");
                break;
            }
            strBuffer.append(s).append("\n");
            dataRowNum++;
        }
    } catch (IOException ex) {
        Logger.getLogger(Text1DConversion.class.getName()).log(Level.SEVERE, null, ex);
    }
    return strBuffer;
}

这段代码用到了Java 8的新特性,但是默认的情况下,netbeans使用的Java 7的语法,因此会爆红

在这里插入图片描述

模块 点击右键,选择 属性

在这里插入图片描述
左边寻找 ,把其修改为 1.8

在这里插入图片描述

这样就不会爆红了,如果你不想使用这种方式,可以替换为如下代码

String curveNamesString = s.replaceFirst("CURNAMES", ""); // 去掉 "CURNAMES" 前缀
String[] curveNamesArray = curveNamesString.split(",");  // 使用逗号分割字符串
for (int i = 0; i < curveNamesArray.length; i++) {
    curveNamesArray[i] = curveNamesArray[i].trim();  // 去除每个名字两端的空格
}
this.curveNames = curveNamesArray;  // 将处理后的数组赋值给成员变量

这个方法的作用就是读取导入的文件的内容,最后展示出来

到这里,就实现了数据的导入功能了,接下来测试

点击上方的 清理和构建项目

在这里插入图片描述
进入当前项目的目录下,找到下面路径下的 .jar

E:\CIFLog-Tutorial\build\cluster\modules

注意,模块里也有build文件夹,我们要进入的是套件里的build,不是模块的
在这里插入图片描述
把产生的 cif-demo-dataimport.jar 放到 D:\CIFLog3x64\conversionJars目录下

在这里插入图片描述

(7)完成导入功能

启动CIFLog软件,这里并不是运行绿色的三角,打开数据转换,导入数据,可以看到成功显示出来了,数据如下

ELLNAME=testwell
STDEP=5860.000000
ENDEP=6546.000000
LEVEL=0.125000
CURNAMES AC,CAL,DEN,GR
    #DEPTH          AC        CAL         DEN        GR
  5860.000000  -9999.00000  5.86100  -9999.00000  37.03200
  5860.125000  -9999.00000  5.84400  -9999.00000  36.18300
  5860.250000  -9999.00000  5.86100  5860.250000  37.11200

在这里插入图片描述

(8)数据导出功能实现与完成

\conversionJars 文件夹里(博主为了测试自己写的模块,把原来的模块放到了一个文件夹里,original文件夹),有已经实现的案例,如果要实现数据导出功能,按照书上的代码是实现不了的,这里给大家说一下,如何查看已经实现好的功能代码

在这里插入图片描述
双击这个jar,例如双击Text1DFormatConversion.jar
在这里插入图片描述
点击左边的conversion,可以看到里面有已经实现的字节码文件,点击去看一个,了解Java的小伙伴是可以看懂的

在这里插入图片描述
例如我用idea打开Text1DConversion.class文件,如下图

在这里插入图片描述
对于数据导出功能,博主这里就不实现了,大家参考已经提供的模块,自行实现一下。

我们打开CIFLog,是可以直接使用已经提供的模块的。

在这里插入图片描述


http://www.kler.cn/a/579656.html

相关文章:

  • 220页满分PPT | 华为ISC供应链解决方案
  • 【新闻资讯】IT 行业最新动向:AI 引领变革,多领域融合加速
  • 【从零开始学习计算机科学】计算机体系结构(一)计算机体系结构、指令、指令集(ISA)与量化评估
  • 不同开发语言对字符串的操作
  • 一文理清概念:数据中台(DMP)-数据仓库(DW)-数据湖(DL)-湖仓一体-数据治理(DG)
  • SpringMVC概述以及入门案例
  • Hadoop、Spark、Flink Shuffle对比
  • 音乐API
  • 渗透测试之利用sql拿shell(附完整流程+防御方案)【下】
  • 机器学习实战——音乐流派分类(主页有源码)
  • 行为模式---观察者模式
  • 生物信息学与计算生物学:各自概念、主要内容、区别与联系、发展展望?
  • Gazebo不报错但是没有机器人模型
  • MySQL配置文件my.cnf和mysql.cnf、mysqld.cnf的区别
  • AI智能体崛起,“智能经济”加速跑,GAI认证助力未来
  • CCF-CSP第36次认证第四题——跳房子【优化思路:预处理区间最大值】
  • 小智智能体语言大模型硬件软件开发
  • 深度解析前端页面性能优化
  • Python零基础学习第三天:函数与数据结构
  • 面试之《vue常见考题》