2017-03-04 6 views
6

मूल पोस्ट एक है कि ज्यादातर लोगों कोजावा में चल रही प्रक्रिया की कार्य निर्देशिका को कैसे पुनर्प्राप्त करें?

का जवाब दे रहे थे यहाँ कोड मैं पहले से ही

String workingDirectory = "/home"; 
String command = "cd ../"; 

ProcessBuilder pb = new ProcessBuilder(new String[] { "cmd", "/c", command }); 
pb.directory(new File(workingDirectory)); 
pb.redirectErrorStream(true); 
Process process = pb.start(); 

// Some time later once the process has been closed 
workingDirectory = pb.directory().getAbsolutePath(); 
System.out.println("Path: " + workingDirectory); 

के साथ ऐसा करने यह काम नहीं करता, इसके समाप्त होने के साथ बाहर आता है की कोशिश की है है वही कार्य निर्देशिका।

किसी भी मदद की सराहना की जाएगी, यह बहुत उपयोगी जानना होगा।

अधिक विशिष्ट होने के लिए, मैं ऊपर दिए गए स्निपेट में जावा में गतिशील रूप से बनाई गई प्रक्रिया की कार्यशील निर्देशिका ढूंढ रहा हूं। यह महत्वपूर्ण है क्योंकि उपरोक्त पूर्वनिर्धारित आदेश, कार्यशील निर्देशिकाएं कभी-कभी बदल सकती हैं, मैं बाद में उपयोग के लिए स्मृति में परिवर्तनों को सहेजना चाहता हूं।

मैं यह करने के लिए एक रास्ता मिल गया है, और यह समस्या मुक्त काम करने के लिए

यहाँ कैसे मैं भेजे कार्यशील निर्देशिका

public int osType = 1; // This is for Windows (0 is for Linux) 

public boolean isValidPath(String path) { 
    try { 
     Paths.get(new File(path).getAbsolutePath()); 
    } catch (InvalidPathException | NullPointerException ex) { 
     return false; 
    } 
    return true; 
} 

public String tracePath(String path) { 
    try { 
     if (!path.contains("%%") && !isValidPath(path)) return null; 
     if (path.contains("%%")) path = path.substring(path.indexOf("%%")); 
     int lastIndex = -1; 
     char filesystemSlash = ' '; 
     if (osType == 0) 
      filesystemSlash = '/'; 
     if (osType == 1) 
      filesystemSlash = '\\'; 
     if (osType == 0) 
      path = path.substring(path.indexOf(filesystemSlash)); 
     if (osType == 1) 
      path = path.substring(path.indexOf(filesystemSlash) - 2); 
     String tmp = path; 
     boolean broken = true; 
     while (!isValidPath(tmp)) { 
      int index = tmp.lastIndexOf(filesystemSlash); 
      if (lastIndex == index) { 
       broken = false; 
       break; 
      } 
      tmp = tmp.substring(0, index); 
      lastIndex = index; 
     } 
     if (broken && lastIndex != -1) { 
      tmp = path.substring(0, lastIndex); 
     } 
     return tmp; 
    } catch (StringIndexOutOfBoundsException ex) { 
     return null; 
    } 
} 

यहाँ से निपटने रहा है लगता है की अनदेखी करने का तरीका है पथ के साथ समस्याएं (इसका उपयोग न करके)

public boolean setDirectory(ProcessBuilder pb, String path) { 
    try { 
     pb.directory(new File(new File(path).getAbsolutePath())); 
     return true; 
    } catch (Exception ex) { 
     return false; 
    } 
} 

अब यहां है कि मैं कैसे हूं विंडोज या लिनक्स के लिए प्रक्रिया शुरू करने

File file = null; 
     if (osType == 1) { 
      ProcessBuilder pb = new ProcessBuilder(new String[] { "cmd", "/c", command + " & echo %% & cd" }); 
      pb.redirectErrorStream(true); 
      if (!workingDirectory.equals("")) 
       setDirectory(pb, workingDirectory); 
      process = pb.start(); 
     } else if (osType == 0) { 
      file = new File("script.sh"); 
      FileWriter writer = new FileWriter(file, false); 
      writer.append(command + " && echo %% && pwd"); 
      writer.flush(); 
      writer.close(); 
      ProcessBuilder pb = new ProcessBuilder(new String[] { "bash", System.getProperty("user.dir") + "/script.sh" }); 
      pb.redirectErrorStream(true); 
      if (!workingDirectory.equals("")) 
       setDirectory(pb, workingDirectory); 
      process = pb.start(); 
     } else 
      return; 

अंत में यहाँ पाश है कि इस प्रक्रिया का प्रबंधन और कार्यशील निर्देशिका

while (process.isAlive() || process.getInputStream().available() > 0) { 
      byte[] returnBytes = new byte[1024]; 
      process.getInputStream().read(returnBytes); 
      char[] arr = new String(returnBytes).trim().toCharArray(); 
      StringBuilder sb = new StringBuilder(); 
      for (int i = 0; i < arr.length; i++) { 
       char c = arr[i]; 
       if (Character.isDefined(c)) 
        sb.append(c); 
      } 
      String response = sb.toString(); 
      if (!response.equals("")) { 
       String path = tracePath(response.trim().replace("\n", "").replace("\r", "")); 
       if (path != null && osType == 1) { 
        if (Paths.get(path).toFile().exists()) 
         workingDirectory = path; 
       } else if (path != null && osType == 0) { 
        if (Paths.get(path).toFile().exists()) 
         workingDirectory = path; 
       } 
       client.sendMessage(response + '\r' + '\n'); 
      } 
     } 
if (file != null) file.delete(); 

यहाँ है प्राप्त आदेश से उत्पादन वेबसाइट

Connecting.. 
Connected. 
Success. You have been connected -> Speentie 

bash -c pwd 
/root/hardsceneServer/remoteServer 

%% 
/root/hardsceneServer/remoteServer 

bash -c cd .. 

%% 
/root/hardsceneServer 

bash -c pwd 
/root/hardsceneServer 

%% 
/root/hardsceneServer 

bash -c dir 
ircServer nohup.out remoteServer start.sh start1.sh start2.sh 

%% 
/root/hardsceneServer 

bash -c cd ircServer 

%% 
/root/hardsceneServer/ircServer 

bash -c dir 
HardScene.jar   hardscene_banned.properties start.sh 
hardscene.properties nohup.out 

%% 
/root/hardsceneServer/ircServer 
+0

क्या आदेश यहाँ है? –

+0

यदि आप पूछ रहे हैं कि किसी अन्य प्रक्रिया की कार्य निर्देशिका को कैसे पुनर्प्राप्त करें, तो यह संभव नहीं है। – Andreas

+0

लिनक्स ऐसा कर सकता है जब यह संभव नहीं है? मैंने सोचा कि जावा मशीन के साथ इंटरफ़ेस भी कर सकता है? एक रास्ता होना चाहिए, भले ही यह बेहद जटिल हो। – Speentie8081

उत्तर

4

है क्या आप इस तरह कुछ ढूंढ रहे हैं?

System.out.println("Current working directory: " + System.getProperty("user.dir")); 
System.out.println("Changing working directory..."); 
// changing the current working directory 
System.setProperty("user.dir", System.getProperty("user.dir") + "/test/"); 

// print the new working directory path 
System.out.println("Current working directory: " + System.getProperty("user.dir")); 

// create a new file in the current working directory 
File file = new File(System.getProperty("user.dir"), "test.txt"); 

if (file.createNewFile()) { 
    System.out.println("File is created at " + file.getCanonicalPath()); 
} else { 
    System.out.println("File already exists."); 
} 

यह आउटपुट:

Current working directory: /Users/Wasi/NetBeansProjects/TestProject 
Changing working directory... 
Current working directory: /Users/Wasi/NetBeansProjects/TestProject/test/ 
File is created at /Users/Wasi/NetBeansProjects/TestProject/test/test.txt 
+0

वास्तव में, आपको लगभग यह नहीं मिला, आप देखते हैं कि जब लोग कमांड विंडो में "cd ../" निष्पादित करते हैं, तो यह उस कमांड के लिए करता है, लेकिन यह उस नई निर्देशिका को जावा में स्मृति में सहेजता नहीं है जो पूरी तरह से नई प्रक्रिया में संग्रहीत है। तो मुझे बस एक प्रक्रिया को पारित करने और उस प्रक्रिया की कार्यशील निर्देशिका प्राप्त करने का कोई तरीका है, ताकि इसे बाद में पुन: उपयोग किया जा सके। – Speentie8081

+0

@SkorrloreGaming मुझे मिल गया। लेकिन आप 'System.getProperty (" user.dir ") का उपयोग क्यों नहीं करते? क्या आप वर्तमान कार्य निर्देशिका को केवल प्रक्रिया के लिए सहेजना चाहते हैं? –

+0

मैं विशेष रूप से गतिशील प्रक्रिया की कार्यशील निर्देशिका चाहता हूं और कुछ भी नहीं – Speentie8081

2

मैं जावा में एक डायनामिक रूप से तैयार की प्रक्रिया के कार्यशील निर्देशिका को खोजने के लिए देख रहा हूँ,

आप निश्चित रूप से कार्यशील निर्देशिका देखने कर सकते हैं user.dir सिस्टम प्रॉपर्टी के मूल्य को देखकर वर्तमान जावा प्रक्रिया:

String cwd = System.getProperty("user.dir"); 

लेकिन की कार्यशील निर्देशिका को खोजने के लिए प्रक्रिया तब तक संभव नहीं है जब तक कि आप विशेष ओएस कॉल का उपयोग नहीं कर रहे हों। लिनक्स पर, यदि आप पिड को जानते हैं तो आप /proc/[pid]/cwd देख सकते हैं लेकिन ओएसएक्स या विंडोज़ में कोई आसान समतुल्य नहीं है जिसे मैं जानता हूं।

यह काम नहीं करता है, एक बार यह खत्म होने के बाद यह एक ही कामकाजी निर्देशिका के साथ आता है।

हाँ, आप कामकाजी निर्देशिका को बदलने के लिए कोई आदेश जारी करने में सक्षम नहीं हैं क्योंकि cmd बाहर निकलने के बाद, कार्य निर्देशिका रीसेट हो जाएगी।

this page के अनुसार, आप user.dir प्रणाली संपत्ति बताए द्वारा कार्यशील निर्देशिका सेट कर सकते हैं:

System.setProperty("user.dir", "/tmp"); 

हालांकि इस ओएस निर्भर हो सकता है और मेरे OSX बॉक्स पर काम नहीं करता। उदाहरण के लिए, निम्नलिखित कोड एक ही निर्देशिका में x1 और x2 फ़ाइलें बनाता है:

new File("x1").createNewFile(); 
// this doesn't seem to do anything 
System.setProperty("user.dir", "/tmp"); 
new File("x2").createNewFile(); 

This answer कहते जावा में ऐसा करने के लिए कोई विश्वसनीय तरीका नहीं है। मैंने हमेशा यह राय ली है कि आप कामकाजी निर्देशिका नहीं बदल सकते हैं और यह कि new File(parent, filename) के साथ विशिष्ट होना चाहिए, यह दिखाने के लिए कि फाइलें कहाँ रहते हैं, आदि ..

0

आप क्या कर सकते हैं विंडोज़

के लिए sysinternals से हैंडल का उपयोग करना है

https://technet.microsoft.com/en-us/sysinternals/bb896655.aspx

या

ls -l/proc/[PID]/fd या pfiles [पीआईडी] linux

और एक फ़ोल्डर है कि पिछले है कि इस प्रक्रिया के द्वारा प्रयोग किया था खोजने के लिए।

String commandToGetOpenFiles="handle... or ls..."; 
BufferedReader reader = new BufferedReader(
     new InputStreamReader(Runtime.getRuntime() 
       .exec(commandToGetOpenFiles).getInputStream())); 

और आप की प्रक्रिया और पीआईडी ​​wmic प्रक्रिया कॉल का उपयोग करें "cmd" यह आपका वर्तमान फ़ाइल निर्देशिका का URL प्राप्त करने

0

उपयोग बनाने मिल शुरू करने के लिए:

URL url = ClassLoader.getSystemResource(FileName); 

यह कहीं भी काम करता है । क्लाउड में भी, बस आपका पीसी नहीं।

यह यूआरएल (java.net) प्रकार देता है। क्लासलोडर के लिए, आपको कुछ भी आयात करने की आवश्यकता नहीं है।

फ़ाइल नाम में, किसी भी फ़ाइल नाम का उपयोग करें जिसके लिए आप पथ प्राप्त करना चाहते हैं।

-1

उपयोग नीचे कोड

Path currentRelativePath = Paths.get(""); 
String s = currentRelativePath.toAbsolutePath().toString(); 
System.out.println("Current relative path is: " + s); 
2

यह जावा में ProcessBuilder के directory() विधि द्वारा प्राप्त नहीं किया जा सकता है क्योंकि यह एक प्रक्रिया का काम कर निर्देशिका, न कि जहां द्विआधारी है निर्धारित करता है। आपको इसे दूसरे स्तर पर करना है।

यदि आप जीएनयू/लिनक्स के साथ काम कर रहे हैं, whereis और update-alternative आपकी सर्वश्रेष्ठ शर्त है। विंडोज़ में, आपके पास where है। अब, यह विभिन्न ओएस में कमांड के उपयोग, और आउटपुट की पार्सिंग के लिए आता है। यह मुश्किल हो सकता है।

कुछ छद्म कोड शुरू करने के साथ:

  1. पैरामीटर के रूप में whereis प्लस आदेश पर अमल उत्पादन पार्स करने के लिए साथ ProcessBuilder
  2. कोशिश,। आप एकाधिक लाइन आउटपुट से निपट सकते हैं।

या,

  1. update-alternatives निष्पादित प्लस पैरामीटर के रूप में आदेश, साथ ProcessBuilder
  2. कोशिश उत्पादन पार्स करने के लिए। एक कमांड के लिए कई विकल्प हो सकते हैं, जैसे java के लिए, आपके पास कुछ अलग जेडीके इंस्टॉल हो सकते हैं।
  3. या, /var/libs/alternatives में सभी लिंक सूचीबद्ध करें और पाइप के साथ आप जो चाहते हैं उसे ढूंढें। आप यहाँ देख सकते हैं:

https://serverfault.com/questions/484896/is-there-a-way-to-list-all-configurable-alternatives-symlinks-for-similar-com

लेकिन, मैं अभी भी संदेह कारण है कि आप यह कर रहे हैं। इसलिए, यदि आप मूल आवश्यकताओं को स्पष्ट कर सकते हैं, तो इससे बहुत मदद मिलेगी। यह X-Y problem से बचने के लिए है।

+0

+1 यह लिनक्स उपयोगकर्ताओं के लिए उपयोगी है, लेकिन परीक्षण में यह अपेक्षित काम नहीं करता है। मैं परियोजना के लिए एक विंडोज और लिनक्स समाधान की तलाश में हूं, हालांकि यह एक नहीं है।शुक्र है, हालांकि, मुझे रिलीज के समय में अपने आप पर एक समाधान मिला। – Speentie8081

+0

तो, आखिरकार आपका समाधान क्या था? यह मुझे रोहचक लगा। – FaithReaper

+0

मैंने सबसे अद्यतन कोड पोस्ट किया है जिसे मैं प्रश्न के संपादन के रूप में उपयोग कर रहा हूं। – Speentie8081

0

आपका प्रश्न है स्पष्ट नहीं एक सा है, लेकिन अगर आप मौजूदा प्रक्रिया के भीतर से वर्तमान निर्देशिका खोजने की कोशिश कर रहे हैं, बस

new File("").getAbsoluteFile().getAbsolutePath(); 
संबंधित मुद्दे