জেআর ফাইলের বাইরে বৈশিষ্ট্য ফাইল পড়ুন


131

আমার কাছে একটি জেআর ফাইল রয়েছে যেখানে আমার সমস্ত কোড চলার জন্য সংরক্ষণাগারভুক্ত রয়েছে। আমাকে এমন একটি বৈশিষ্ট্য ফাইল অ্যাক্সেস করতে হবে যা প্রতিটি রানের আগে পরিবর্তন / সম্পাদনা করা দরকার। আমি JAR ফাইল যেখানে আছে সেখানে ডিরেক্টরি ফাইলটি রাখতে চাই। যাইহোক জাভা কে সেই ডিরেক্টরি থেকে সম্পত্তিগুলির ফাইলটি তুলতে বলার আছে?

দ্রষ্টব্য: আমি সম্পত্তি ডিরেক্টরিটি হোম ডিরেক্টরিতে রাখতে বা কমান্ড লাইন আর্গুমেন্টে সম্পত্তি ফাইলের পথটি পাস করতে চাই না pass


2
দেখুন এই উত্তর - "পরিবর্তে জার ভিতরে 'ডিফল্ট' ফাইল সংরক্ষণ এটি পরিবর্তন করা হয়, তাহলে অন্য স্থানে পরিবর্তিত ফাইল সংরক্ষণ ওয়ান সাধারণ স্থানের একটি উপ-ডিরেক্টরি।। user.homeযখন ফাইলের জন্য চেক, প্রথম অস্তিত্ব চেক করুন। ফাইল সিস্টেমে একটি পরিবর্তিত ফাইল এবং এটি উপস্থিত না থাকলে ডিফল্ট ফাইলটি লোড করুন। বিটিডাব্লু "আমি চাই না .." আপনি যা চান তা কী কাজ করে এবং ব্যবহারিক তার চেয়ে কম গুরুত্বপূর্ণ। অ্যাপ্লিকেশন সংরক্ষণ করা হচ্ছে। অ্যাপ্লিকেশন ডিরেক্টরিতে সেটিংস অরাকল এবং এমএস (এবং সম্ভবত অন্যরা) উভয়ই দৃ strongly়ভাবে নিরুৎসাহিত করেছেন।
অ্যান্ড্রু থম্পসন

3
জার ডিরেক্টরিতে আমার সম্পত্তি ফাইল রাখার কারণ হ'ল পুরো ডিরেক্টরিটি (জার এবং সম্পত্তি সহ) অন্য কোনও মেশিনে অনুলিপি করে চালানো হলে এগুলি একত্রে রাখা ভাল।
নিল

এবং যদি আমি ব্যবহারকারীকে সম্পত্তি ফাইলের পাথটি পাস করার জন্য বাধ্য করি তবে প্রতিবার যখন সে কোনও আলাদা মেশিন থেকে ব্যাচ ফাইল চালায় তখন তাকে পরিবর্তন করতে হবে।
নীল

উত্তর:


144

সুতরাং, আপনি আপনার .propertiesফাইলটিকে একই / ফোল্ডারে মূল / চলমানযোগ্য জারের হিসাবে ফাইলটিকে প্রধান / চলমানযোগ্য জারের উত্স হিসাবে বিবেচনা করতে চান । সেক্ষেত্রে আমার নিজের সমাধানটি নিম্নরূপ:

প্রথম জিনিস: আপনার প্রোগ্রাম ফাইল আর্কিটেকচারটি এর মতো হবে (ধরে নিলে আপনার মূল প্রোগ্রামটি মূল.ইনার এবং এর প্রধান বৈশিষ্ট্যগুলির ফাইলটি মূল pষধি):

./ - the root of your program
 |__ main.jar
 |__ main.properties

এই আর্কিটেকচারের সাহায্যে, আপনার মেইন.জার চলমান আগে (প্রোগ্রামের বর্তমান অবস্থার উপর নির্ভরশীল) চলমান পূর্বে বা চলাকালীন কোনও পাঠ্য সম্পাদক ব্যবহার করে আপনি মূল.প্রপার্টি ফাইলগুলিতে যে কোনও সম্পত্তি পরিবর্তন করতে পারেন কারণ এটি কেবল একটি পাঠ্য-ভিত্তিক ফাইল। উদাহরণস্বরূপ, আপনার main.properties ফাইলটিতে এটি থাকতে পারে:

app.version=1.0.0.0
app.name=Hello

সুতরাং, আপনি যখন আপনার মূল প্রোগ্রামটি মূল / বেস ফোল্ডার থেকে চালাবেন, সাধারণত আপনি এটিকে এভাবে চালাবেন:

java -jar ./main.jar

বা, সরাসরি:

java -jar main.jar

আপনার মেইন.জারে, আপনার মেইন.প্রপার্টি ফাইলগুলিতে প্রাপ্ত প্রতিটি সম্পত্তির জন্য আপনাকে কয়েকটি ইউটিলিটি পদ্ধতি তৈরি করতে হবে; যাক নীচে app.versionসম্পত্তিটির getAppVersion()পদ্ধতি থাকবে :

/**
 * Gets the app.version property value from
 * the ./main.properties file of the base folder
 *
 * @return app.version string
 * @throws IOException
 */

import java.util.Properties;

public static String getAppVersion() throws IOException{

    String versionString = null;

    //to load application's properties, we use this class
    Properties mainProperties = new Properties();

    FileInputStream file;

    //the base folder is ./, the root of the main.properties file  
    String path = "./main.properties";

    //load the file handle for main.properties
    file = new FileInputStream(path);

    //load all the properties from this file
    mainProperties.load(file);

    //we have loaded the properties, so close the file handle
    file.close();

    //retrieve the property we are intrested, the app.version
    versionString = mainProperties.getProperty("app.version");

    return versionString;
}

মূল প্রোগ্রামটির যে কোনও অংশে যেটির app.versionমান প্রয়োজন হয়, আমরা তার পদ্ধতিটিকে নীচে কল করি:

String version = null;
try{
     version = getAppVersion();
}
catch (IOException ioe){
    ioe.printStackTrace();
}

7
এই সমাধান কাজ করে। সঠিক প্রয়োজনীয়তা এবং বিশদ কোড বোঝার জন্য ধন্যবাদ। আমি যাচাই করেছি যে সম্পত্তি ফাইলটি জার ফাইলের মধ্যে নেই তবে তবুও এটি একই ডিরেক্টরি থেকে ফাইলটি অ্যাক্সেস করতে পারে যেখানে জার ফাইল রয়েছে। এই পথে কোনও নিখুঁত পাথ হার্ড কোডের প্রয়োজন নেই। এখন জার এবং সম্পত্তি ফাইল উভয় যে কোনও ডিরেক্টরিতে অনুলিপি করতে এবং স্বাধীনভাবে চালানো যেতে পারে।
নীল

3
প্রাক্তন: ava ava জাভা-জার-বিল্ড / মেইন.জার}} এর বাইরে থেকে কমান্ডটি কার্যকর করলে ফাইলটি পাওয়া যাবে না} আপনার কি এটির কোনও সমাধান আছে, @ আইই?
ডায়রিয়ান

@ দারিয়ান এখানে ঠিক করার মতো কিছুই নেই; এটি কেবল ডিজাইন করা হিসাবে কাজ করে যেখানে ./ফাইল সংস্থার আর্কিটেকচারে আমি যা বর্ণনা করেছি সে হিসাবে জার এবং বৈশিষ্ট্যগুলি ফাইল একই মূল ফোল্ডারে (একই ডিরেক্টরি স্তর) থাকতে হবে। (যেমন প্রয়োজন সেট প্রতি মূল পোস্টার)
ecle

@ ডায়ারিয়ান, সুতরাং যদি আপনি কার্যকর করতে চান তবে আপনাকে java -jar build/main.jarসম্পত্তি ফাইলটি buildফোল্ডারেও রাখা দরকার যাতে এটি জারের মতো একই ডিরেক্টরি স্তরে থাকে।
খালি

7
আপনার প্রতিক্রিয়াটির জন্য ধন্যবাদ @ আইই, সমস্যাটি আমি জানি না যে ব্যবহারকারীরা কোথায় এটি কার্যকর করবে java -jar path/to/jar/file। তবে আমি অন্য একটি প্রশ্নের সমাধান পেয়েছি:String path = ClassLoader.getSystemClassLoader().getResource(".").getPath() + "/main.properties";
ডায়রিয়ান

42

আমি এটি অন্য উপায়ে করেছিলাম।

Properties prop = new Properties();
    try {

        File jarPath=new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath());
        String propertiesPath=jarPath.getParentFile().getAbsolutePath();
        System.out.println(" propertiesPath-"+propertiesPath);
        prop.load(new FileInputStream(propertiesPath+"/importer.properties"));
    } catch (IOException e1) {
        e1.printStackTrace();
    }
  1. জার ফাইলের পাথ পান।
  2. এই ফাইলটির মূল ফোল্ডারটি পান।
  3. আপনার বৈশিষ্ট্যগুলির ফাইলের নাম সহ ইনপুটস্ট্রিমপথে সেই পথটি ব্যবহার করুন।

এর পরিবর্তে আমি ব্যবহার করেছি পিতামাতা ফাইল () অংশটি ফেলে দিতে হয়েছিল: স্ট্রিং প্রপার্টিপথ = জারপথ.সেটআবলসপথ (); তবে ফাইলটি কোথায় রয়েছে তার উপরে এটি নির্ভর করে
মোবাইলমনে

4
জাস্ট প্রতিস্থাপন "jarPath.getParentFile ()। GetAbsolvePath ();" "jarPath.getParent ()" এ যান। তখন কবজির মতো কাজ করে।
স্ট্যাকএডিক্টেট

1
আমার ক্ষেত্রে একই সমস্যা তবে আমার স্প্রিং বেস প্রকল্প রয়েছে। জার ফাইলের পাশে সেই ফাইলটি বসন্তকে কীভাবে বলা যায়? কোনও ধারণা
মুবাশ্বের

3

একটি জার ফাইল থেকে আপনার ফাইল ডিরেক্টরিতে ফাইল অ্যাক্সেস করার ক্ষেত্রে সর্বদা সমস্যা হয়। একটি জার ফাইলে ক্লাসপাথ সরবরাহ করা খুব সীমাবদ্ধ। পরিবর্তে আপনার প্রোগ্রাম শুরু করতে ব্যাট ফাইল বা একটি sh ফাইল ব্যবহার করার চেষ্টা করুন। সেই পদ্ধতিতে আপনি যে কোনও উপায়ে আপনার ক্লাসপাথটি নির্দিষ্ট করতে পারেন, সিস্টেমের যে কোনও জায়গায় যে কোনও ফোল্ডারটি উল্লেখ করতে পারেন।

এই প্রশ্নের আমার উত্তরটিও পরীক্ষা করে দেখুন:

স্কোয়াসাইটযুক্ত জাভা প্রকল্পের জন্য .exe ফাইল তৈরি করা


1

আমার অনুরূপ কেস রয়েছে: আমার *.jarফাইলটি বলা *.jarফাইলটির পাশের ডিরেক্টরিতে একটি ফাইল অ্যাক্সেস করতে চাই । পড়ুন এই উত্তর হিসাবে ভাল।

আমার ফাইল কাঠামোটি হ'ল:

./ - the root of your program
|__ *.jar
|__ dir-next-to-jar/some.txt

নিম্নলিখিত ফাইলগুলির সাথে আমি some.txtইনপুট স্ট্রিমে একটি ফাইল (বলুন ) লোড করতে সক্ষম হলাম *.jar:

InputStream stream = null;
    try{
        stream = ThisClassName.class.getClass().getResourceAsStream("/dir-next-to-jar/some.txt");
    }
    catch(Exception e) {
        System.out.print("error file to stream: ");
        System.out.println(e.getMessage());
    }

তারপরে আপনি যা চান তা করুন stream


0

আমার কাছে ক্লাসপথ দ্বারা বা লগ 4j2.properties সহ বাহ্যিক কনফিগারেশন উভয়েরই করার উদাহরণ রয়েছে

package org.mmartin.app1;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.LogManager;


public class App1 {
    private static Logger logger=null; 
    private static final String LOG_PROPERTIES_FILE = "config/log4j2.properties";
    private static final String  CONFIG_PROPERTIES_FILE = "config/config.properties";

    private Properties properties= new Properties();

    public App1() {
        System.out.println("--Logger intialized with classpath properties file--");
        intializeLogger1();
        testLogging();
        System.out.println("--Logger intialized with external file--");
        intializeLogger2();
        testLogging();
    }




    public void readProperties()  {
        InputStream input = null;
        try {
            input = new FileInputStream(CONFIG_PROPERTIES_FILE);
            this.properties.load(input);
        } catch (IOException e) {
            logger.error("Unable to read the config.properties file.",e);
            System.exit(1);
        }
    }

    public void printProperties() {
        this.properties.list(System.out);
    }

    public void testLogging() {
        logger.debug("This is a debug message");
        logger.info("This is an info message");
        logger.warn("This is a warn message");
        logger.error("This is an error message");
        logger.fatal("This is a fatal message");
        logger.info("Logger's name: "+logger.getName());
    }


    private void intializeLogger1() {
        logger = LogManager.getLogger(App1.class);
    }
    private void intializeLogger2() {
        LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false);
        File file = new File(LOG_PROPERTIES_FILE);
        // this will force a reconfiguration
        context.setConfigLocation(file.toURI());
        logger = context.getLogger(App1.class.getName());
    }

    public static void main(String[] args) {
        App1 app1 = new App1();
        app1.readProperties();
        app1.printProperties();
    }
}


--Logger intialized with classpath properties file--
[DEBUG] 2018-08-27 10:35:14.510 [main] App1 - This is a debug message
[INFO ] 2018-08-27 10:35:14.513 [main] App1 - This is an info message
[WARN ] 2018-08-27 10:35:14.513 [main] App1 - This is a warn message
[ERROR] 2018-08-27 10:35:14.513 [main] App1 - This is an error message
[FATAL] 2018-08-27 10:35:14.513 [main] App1 - This is a fatal message
[INFO ] 2018-08-27 10:35:14.514 [main] App1 - Logger's name: org.mmartin.app1.App1
--Logger intialized with external file--
[DEBUG] 2018-08-27 10:35:14.524 [main] App1 - This is a debug message
[INFO ] 2018-08-27 10:35:14.525 [main] App1 - This is an info message
[WARN ] 2018-08-27 10:35:14.525 [main] App1 - This is a warn message
[ERROR] 2018-08-27 10:35:14.525 [main] App1 - This is an error message
[FATAL] 2018-08-27 10:35:14.525 [main] App1 - This is a fatal message
[INFO ] 2018-08-27 10:35:14.525 [main] App1 - Logger's name: org.mmartin.app1.App1
-- listing properties --
dbpassword=password
database=localhost
dbuser=user

0

এটি আমার পক্ষে কাজ করে। এ থেকে আপনার সম্পত্তি ফাইল লোড করুনcurrent directory

Properties properties = new Properties();
properties.load(new FileReader(new File(".").getCanonicalPath() + File.separator + "java.properties"));
properties.forEach((k, v) -> {
            System.out.println(k + " : " + v);
        });

নিশ্চিত করুন, java.propertiesএটি আছে current directory। আপনি কেবল একটি সামান্য স্টার্টআপ স্ক্রিপ্ট লিখতে পারেন যা আগের মতো সঠিক ডিরেক্টরিতে স্যুইচ করে

#! /bin/bash
scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 
cd $scriptdir
java -jar MyExecutable.jar
cd -

java.propertiesআপনার আইডিই থেকে এই কোডটি কাজ করার জন্য আপনার প্রকল্পে কেবল ফাইলটিকে আপনার প্রকল্পের মূলের মধ্যে রাখুন।


0

এখানে যদি আপনি উল্লেখ করেন .getPath()তবে এটি জারের পথ ফিরে আসবে এবং আমি অনুমান করি যে জারের সাথে স্থাপন করা সমস্ত অন্যান্য কনফিগারেশন ফাইলগুলি উল্লেখ করার জন্য আপনাকে এর পিতামাতার প্রয়োজন হবে। এই কোডটি উইন্ডোজে কাজ করে। মূল শ্রেণীর মধ্যে কোড যুক্ত করুন।

File jarDir = new File(MyAppName.class.getProtectionDomain().getCodeSource().getLocation().getPath());
String jarDirpath = jarDir.getParent();

System.out.println(jarDirpath);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.