2013-08-12 32 views

risposta

6

Poiché Groovy gira su JVM, si applicano le stesse restrizioni. Sfortunatamente non è possibile.

Changing the current working directory in Java?

JDK bug

+0

ieri che cerco su StackOverflow, può funzionare in questo modo:? 'Vuoto SetCurrentDirectory (new_dir_path) { \t System.setProperty ("user.dir", new_dir_path) }' – Joe

+0

@ Joe No non lo farà, leggi la domanda Java che ho collegato. –

+0

Sì. Ho provato, non lo farà. Grazie. – Joe

4

Se è possibile eseguire altri script come processo separato, si può dare ProcessBuilder parametro dir di lavoro:

def processBuilder=new ProcessBuilder(command) 
processBuilder.directory(new File("Working dir")) 
def process = processBuilder.start() 

o

command.execute(null, new File("Working dir")) 

così quel processo passerà alla tua nuova cartella ed eseguirlo lì.

1

Java/groovy in realtà non "ha" una directory di lavoro per quanto posso dire. La shell che ha lanciato groovy ha uno e qualsiasi "comando" figlio ereditato da quella shell in modo diretto.

Anche Java sembra leggere la directory corrente della shell e memorizzarla in "user.dir". Questo è usato come base per l'oggetto "File", quindi se System.setProperty ("user.dir", "c:/windows") cambierà le future chiamate di nuovo File (".") Ma non cambierà il directory della shell padre (e quindi non le directory figlio).

Qui ci sono tre "work-around" che può funzionare per diversi scenari:

1) I tipi di superato questo per un compito ben preciso ... Ho voluto attuare "CD" come uno script Groovy. Era possibile solo perché tutti i miei script venivano già "incapsulati" in un file batch. Ho fatto in modo che il mio script potesse creare un file chiamato "afterburner.cmd" che, se esistesse, verrebbe eseguito quando lo script termina. C'erano alcuni trucchi per i file batch per far funzionare questo.

Un file cmd di avvio potrebbe anche "impostare" la directory corrente prima di richiamare il tuo script/app groovy.

A proposito, Avere un cmd di avvio è stato molto più utile di quanto avrei pensato sarebbe - Rende il tuo ambiente costante e ti permette di distribuire più facilmente i tuoi "Script" su altre macchine. Ho persino il mio compito di compilare i miei script su .classes perché si è rivelato più veloce per compilare un .groovy su un .class e avviare la classe .class con "Java" piuttosto che eseguire lo script con "groovy" - e di solito puoi saltare il passo di compilazione che lo rende MOLTO più veloce!

2) Per alcuni piccoli comandi, si potrebbe scrivere un metodo come questo:

def currentDir = "C:\\" 
def exec(command, dir = null) { 
    "cmd /c cd /d ${dir?:currentDir} && $command".execute().text 
} 

// Default dir is currentDir 
assert exec("dir").endsWith("C:\\>") 

// different dir for this command only 
assert exec("dir", "c:\\users").endsWith("C:\\users") 

// Change default dir 
currentDir = "C:\\windows" 
assert exec("dir").endsWith("C:\\windows") 

sarà più lento di "" .execute() se "cmd" non è richiesto.

3) Codice di una piccola classe che mantiene una shell di comando "Apri" (ho fatto questo una volta, c'è un po 'di complessità), ma l'idea è:

def process="cmd".execute() 
def in=process.in 
def out=process.out 
def err=process.err 

ora "in" è un flusso di input da cui è possibile eseguire lo spin off/read from e "out" è un flusso di output a cui è possibile scrivere comandi, tenere d'occhio "err" per rilevare gli errori.

La classe deve scrivere un comando per l'output, leggere l'input fino al completamento del comando, quindi restituire l'output all'utente.

Il problema sta rilevando quando l'output di un dato comando è completo. In generale è possibile rilevare un prompt "C: ..." e assumere che ciò significhi che il comando ha terminato l'esecuzione. Puoi anche usare un timeout. Entrambi sono abbastanza fallibili. È possibile impostare la richiesta di quella shell su qualcosa di unico per renderla molto meno fallibile.

Il vantaggio è che questa shell può rimanere aperta per tutta la vita della tua app e può aumentare notevolmente la velocità poiché non si creano ripetutamente shell "cmd". Se si crea una classe (chiamiamolo "CommandShell") che avvolge l'oggetto del processo, allora dovrebbe essere veramente facile da usare:

def cmd=new CommandShell() 
println cmd.execute("cd /d c:\\") 
println cmd.execute("dir") // Will be the dir of c:\ 

ho scritto una classe Groovy come questo, una volta, si tratta di un sacco di sperimentare e la vostra l'istanza può essere trashed da comandi come "exit" ma è possibile.

Problemi correlati