Java文件的相对路径规则

news2024/11/24 19:14:32

前言

最近做项目,又涉及到Linux Java文件的相对路径,但是相对路径在不同的服务器或者docker上居然不一样,这个就很难受,只能用绝对路径解决,因为绝对路径是固定的路径,但是相对路径为什么会在不同的服务器不一样呢?

Java源码分析与Demo

因为文件夹或者文件的创建是native方式C++实现的,笔者本地是MacOS系统,Linux类似

创建目录如上,创建文件如下:

 

 功能大同小异,毕竟Linux一切皆文件,注意默认情况下Linux Java创建文件夹是777的权限,跟umask也相关。

创建Demo 代码

public class Main {
    public static void main(String[] args) throws InterruptedException {
        File file = new File("hello");
        boolean ok = file.mkdir();

        System.out.println(file.getAbsoluteFile());

        if (ok) {
            Thread.sleep(60*1000);
            file.delete();
        }
    }
}

 运行后结果

为什么是项目的根目录??? 如果加上-Duser.dir=xxx的JVM参数,那么Java绝对路径是不正确的

C++原理与Demo

为了验证这个是为什么,构建JNI代码,注意JNI非常关键的包名

package org.example;

public class Demo {

    public native String sayHello(File file);
}

在java目录下,执行javah org.example.Demo

生成C++头文件,原因是idea把java目录作为classpath;也可以使用-cp指定classpath,javah 默认支持-jni可以不写

创建C++ lib文件

 但是头文件在放在C++项目中执行cmake时,报错

Could NOT find JNI (missing: JAVA_INCLUDE_PATH JAVA_INCLUDE_PATH2 AWT)

明明已经设置了JAVA_HOME,但是还是不行,查询资料,cmake官方资料,解决问题准确FindJNI — CMake 3.27.0 Documentation

只需在CMakeLists文件中设置,根据自己的实际情况而定

# JAVA_INCLUDE_PATH为jni.h所在路径,一般在jdk目录下的include中
set(JAVA_INCLUDE_PATH /Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home/include)
# JAVA_INCLUDE_PATH2为jni_md.h所在路径,一般在jdk目录下的include/xxx系统类别目录中
set(JAVA_INCLUDE_PATH2 /Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home/include/darwin)

set(JAVA_AWT_INCLUDE_PATH /Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home/include)

注意cmakelists文件的lib命名,可自定义

add_library(org_example_Demo SHARED org_example_Demo.cpp) 

这个名称就是Java代码加载的名称,编译代码构建可执行文件就可以得到lib文件,linux是so文件

    static {
        System.loadLibrary("org_example_Demo");
    }

    public static void main(String[] args) {
        File file = new File("demo");
        String path = new Demo().sayHello(file);
        System.out.println(path);
    }

加入JVM参数-Djava.library.path=xxx目录,启动即可执行

C++可执行代码

#include "org_example_Demo.h"
#include <jni.h>
#include <iostream>
#include <sys/stat.h>

using namespace std;

//实现sayHello方法
JNIEXPORT jstring JNICALL Java_org_example_Demo_sayHello(JNIEnv* env, jobject obj, jobject file) {
    jclass fileClass = env->FindClass("java/io/File");
    if (!fileClass) return NULL;
    jfieldID path = env->GetFieldID(fileClass,"path", "Ljava/lang/String;");
    jstring jstr = static_cast<jstring>(env->GetObjectField(file, path));

    int success = mkdir("demo", 0777);
    cout << success << endl;
    return jstr;
}

在拿到文件后使用path创建文件,这里仿造JDK的实现,先通过类读取fieldid,然后读取field,这里直接强转jstring了

读取field,JDK使用宏定义

参考Java jni.h C++数据类型

javajni定义的类型与C++类C++字节数
booleanjbooleanunsigned char1
bytejbytesigned char1
charjcharunsigned short2
shortjshortshort2
intjint/jsizelong4
longjlong__int648
floatjfloatfloat4
doublejdoubledouble8
Stringjstringstring(char*)

 

 

执行Java的main方法

 说明相对路径是C代码函数执行的结果;但是当mkdir使用相对路径时,如果在C++的环境执行,直接就失败

 可以看到结果是-1。JNI执行和C++原生执行的结果是不一样的😳,如果使用绝对路径可以成功

得出结论,JNI中间的一些设置数据跟C、C++底层函数执行结果相关性很大,比如创建目录或者文件,在相对路径下,C++不能成功;Java却可以成功。

总结

linux、unix环境下Java创建相对路径,表现为C、C++的函数执行,但是跟C++等原生执行的结果不一样,JNI在C类代码执行时,使用的堆外空间,里面是有一些默认设定的,比如创建相对路径的目录,JNI会默认使用项目的根路径,作为堆外空间,在linux的服务器上,可能与user.dir有关联

 笔者在配置user.dir的linux docker上出现过不一致的情况,相同JVM参数(-Duser.dir)不同的docker容器创建的相对路径不一致,猜测JVM的native空间,可能跟user.dir和docker的work.dir都有关系,需要进一步查看JNI的执行原理和C++函数的源码进一步分析。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/786435.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

将pdf转换成word怎么转换?掌握这几个转换方法就够了

将pdf转换成word怎么转换&#xff1f;将 PDF 转换成 Word 文档是一个常见的需求&#xff0c;我们需要编辑 PDF 文件中的文字内容&#xff0c;但是 PDF 文件并不方便直接编辑。下面介绍几个转换方法。 方法一&#xff1a;使用迅捷 PDF 转换器 这是一款专业的 PDF 转换工具&…

【2023】HashMap详细源码分析解读

前言 在弄清楚HashMap之前先介绍一下使用到的数据结构&#xff0c;在jdk1.8之后HashMap中为了优化效率加入了红黑树这种数据结构。 树 在计算机科学中&#xff0c;树&#xff08;英语&#xff1a;tree&#xff09;是一种抽象数据类型&#xff08;ADT&#xff09;或是实作这种…

2023年深圳杯数学建模 D题 基于机理的致伤工具推断

致伤工具的推断一直是法医工作中的热点和难点。由于作用位置、作用方式的不同&#xff0c;相同的致伤工具在人体组织上会形成不同的损伤形态&#xff0c;不同的致伤工具也可能形成相同的损伤形态。致伤工具品种繁多、形态各异&#xff0c;但大致可分为两类&#xff1a;锐器&…

结构体——位段

//结构体--位段 &#xff08;位 指二进制位 &#xff09; // 位段的声明与结构体是类似的 // 1&#xff0c;位段的成员必须是 int &#xff0c;unsigned int 或 signed int // 2&#xff0c;位段的成员名后边有一个冒号和一个数字。&#xff08;数字表示开辟需要的比特位个数&a…

【【51单片机的温度识别】】

51单片机的温度识别 这么热的天&#xff0c;再离我远一点 DS18B20温度读取 温度报警 我们这里对于单总线 也仿照I2C 总线的模样 以下是我们实现的onewire.c文件 #include <REGX52.H> //第一步从原理图触发先定义端口sbit OneWire_DQP3^7;//第一步初始化unsigned char…

商城-学习整理-基础-前端(四)

目录 一、技术栈介绍二、ES61、简介2、什么是ECMAScript3、ES6 新特性1、let 声明变量2、const 声明常量&#xff08;只读变量&#xff09;3、解构表达式1&#xff09;数组解构2&#xff09;对象解构 4、字符串扩展1&#xff09;、几个新的 API2&#xff09;、字符串模板 5、函…

跨洋消息队列CKafka

背景 跨洋消息队列CKafka&#xff0c;是腾讯出品开源消息队列组件&#xff0c;为了解决客户跨地域容灾、冷备的诉求跨地域秒级准实时数据同步而开源的腾讯云中间件。 整体架构图 数据同步主要流程 Connect 集群初始化 Connect Task&#xff0c;每个 Task 会新建多个 Worker C…

3D元宇宙游戏,或许能引爆新的文娱消费增长点

从去年开始&#xff0c;在互联网上&#xff0c;一个名为【神念无界-源起山海】的元宇宙游戏项目火了。除了可以在游戏内体验独战、团队式作战等3D古风经典游戏场景和玩法&#xff0c;还有钓鱼增加能量、情侣姻缘一线牵&#xff0c;结婚等多元化逼真效果与玩法&#xff0c;这令很…

第118天:免杀对抗-二开CS上线流量特征Shellcode生成机制反编译重打包(上)

知识点 #知识点&#xff1a; 1、CS-表面特征消除 2、CS-HTTP流量特征消除 3、CS-Shellcode特征消除#章节点&#xff1a; 编译代码面-ShellCode-混淆 编译代码面-编辑执行器-编写 编译代码面-分离加载器-编写 程序文件面-特征码定位-修改 程序文件面-加壳花指令-资源 代码加载面…

opencv-21 alpha 通道详解(应用于 图像增强,合成,蒙版,特效 等)

什么是alpha 通道&#xff1f; Alpha通道是计算机图形学中用于表示图像透明度的一种通道。在一个图像中&#xff0c;通常会有三个颜色通道&#xff1a;红色&#xff08;R&#xff09;、绿色&#xff08;G&#xff09;、蓝色&#xff08;B&#xff09;&#xff0c;它们合在一起…

将Parasoft和ChatGPT相结合会如何?

ChatGPT是2023年最热门的话题之一&#xff0c;是OpenAI训练的语言模型。它能够理解和生成自然语言文本&#xff0c;并接受过大量数据的训练&#xff0c;包括用各种编程语言编写的许多开源项目的源代码。 软件开发人员可以利用大量的知识库来协助他们的工作&#xff0c;因为它具…

网络安全高级课笔记1

HTML字符编码/HTML实体编码 html实体编码 unicode urlcode 在字符的十六进制前加百分号&#xff08;%&#xff09;&#xff0c;用于浏览器的网址输入框 utf-8 字符数字表示法 HTML允许使用Nuicode码点表示字符&#xff0c;浏览器会自动将码点转成对应的字符。 字符的码点表…

vtk能否被OpenGL和DirectX取代?

VTK&#xff08;Visualization Toolkit&#xff09;是一个强大的开源可视化库&#xff0c;用于处理和呈现各种科学数据。它建立在OpenGL和DirectX等底层图形库之上&#xff0c;提供了高级的可视化功能和算法。虽然OpenGL和DirectX可以用于图形渲染和实时图形处理&#xff0c;但…

数据结构--线性表2-1

目录 一、线性结构的定义 二、线性表的表示 三、顺序表的实现&#xff08;或操作&#xff09; 1、修改&#xff1a; 2、插入&#xff1a; 四、顺序表的运算效率分析&#xff1a;时间效率分析&#xff1a; 一、线性结构的定义 若结构时非空有限集&#xff0c;则有且仅有一个…

python爬虫基础入门——利用requests和BeautifulSoup

(本文是自己学习爬虫的一点笔记和感悟) 经过python的初步学习,对字符串、列表、字典、元祖、条件语句、循环语句……等概念应该已经有了整体印象,终于可以着手做一些小练习来巩固知识点,写爬虫练习再适合不过。 1. 网页基础 爬虫的本质就是从网页中获取所需的信息,对网…

优化帮助与支持中心,提升客户满意度

在竞争激烈的商业环境中&#xff0c;提供良好的客户体验和有效的支持服务是企业获得成功的关键因素之一。优化帮助与支持中心的设计和运营对于提升客户满意度至关重要。本文将探讨如何通过优化帮助与支持中心来提升客户满意度&#xff0c;并为企业带来更多的商业机会。 提供多…

2023年深圳杯数学建模 A题 影响城市居民身体健康的因素分析

以心脑血管疾病、糖尿病、恶性肿瘤以及慢性阻塞性肺病为代表的慢性非传染性疾病&#xff08;以下简称慢性病&#xff09;已经成为影响我国居民身体健康的重要问题。随着人们生活方式的改变&#xff0c;慢性病的患病率持续攀升。众所周知&#xff0c;健康状况与年龄、饮食习惯、…

【计算机视觉 | 图像分割】arxiv 计算机视觉关于图像分割的学术速递(7 月 25 日论文合集)

文章目录 一、分割|语义相关(17篇)1.1 Semi-Supervised Medical Image Segmentation with Co-Distribution Alignment1.2 CTVIS: Consistent Training for Online Video Instance Segmentation1.3 SL: Stable Learning in Source-Free Domain Adaption for Medical Image Segme…

16_LinuxLCD驱动

目录 Framebuffer设备 LCD驱动简析 LCD驱动程序编写 LCD屏幕参数节点信息修改 LCD 屏幕背光节点信息 使能Linux logo显示 设置LCD作为终端控制台 Framebuffer设备 先来回顾一下裸机的时候LCD驱动是怎么编写的,裸机LCD驱动编写流程如下: 1.初始化I.MX6U的eLCDIF控制器,…

【代码随想录day19】找树左下角的值

题目 思路 这题最直观的方法就是用层序遍历&#xff0c;记录一下每一层的左边第一个节点&#xff0c;这样整个层序遍历一遍就能找到最后一行最左边的节点。这里要注意最左边的节点不一定是父节点的左子节点&#xff01;&#xff01;&#xff01;如果最后一行没有左子节点&…