2016-03-07 5 views
0

Я бегу ниже запрос через Java на использовании PSQL Postgres БД:полная команда CMD не работает с Java

psql.exe -U <user> -w -h <host> -d <db_name> -a -f <file> 2> "<path_to_file>\psql.log" 

Первоначально, в течение некоторого времени программа Java сделал создать файл. Затем я столкнулся с другой проблемой, что она не переписывает файл журнала. Поэтому я использовал функцию file.delete() после каждого создания этого файла журнала через java.

Теперь Java по какой-то причине даже не создает файл журнала. Если я запустил вышеприведенное вручную в командной строке, он работает абсолютно нормально, но не через java-код. Я вижу, что эта команда запускается в журнале java, но она не создает файл журнала, даже когда я удалил функцию file.delete()

Я много исследовал, но не смог найти решение. Любая помощь будет высоко оценен.

его длинный код..так я скажу вам соответствующую часть.

Я вызываю функцию из потока. Код ниже для этой функции:

public static void SaveACopyfileToServer(int auditid,String filepath,String fname,String tb_name,String plpgsql_path) throws Exception 
    { 
     Map<String, String> env = System.getenv(); 

     String plpgsql = "\""+plpgsql_path+"\" -U "+env.get("PG_USER")+" -w -h "+env.get("PG_HOST")+" -d "+env.get("PG_DB")+" -a -f "+"\""+filepath+"copy_"+tb_name+auditid+".sql\" 2> \"C:\\ER\\ETL\\logs\\psql.log\""; 
     System.out.println(plpgsql); 
     Process p = Runtime.getRuntime().exec(plpgsql); 
     p.getOutputStream().close(); 
     p.waitFor(); 

     SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS"); 
     Calendar cal10 = Calendar.getInstance(); 
     System.out.println("Data loaded for "+tb_name+auditid+" at "+sdf.format(cal10.getTime())); 
    } 

После этого я звоню другую функцию, которая:

public static void extracterrorreason(String fname,int auditid,String sessionid,Connection con_pg) throws FileNotFoundException, IOException, InterruptedException{ 
    File file = new File("C:\\ER\\ETL\\logs\\psql.log"); 

    if(file.exists()) 
    { 
     System.out.println("File present"); 
     } 
    else 
     { 
     System.out.println(file+" not found"); 
     } 
    if (file.length()!=0){ 
     System.out.println("Log file being read is "+file); 
        BufferedReader br = new BufferedReader(new FileReader(file)); 
        String line = br.readLine(); 
        String out_err = line.substring(line.indexOf("ERROR")); 

        System.out.println(out_err); 
        System.out.println("Error while loading the file into Database for file "+fname); 

        String comment = "CopyToStage','"+out_err; 
          Utils.updateAuditDetailTable(auditid, sessionid, -1, comment, true, con_pg,""); 

        br.close(); 
        //file.delete(); 
       } 
} 

Первая функция, используемая для создания файла psql.log, но теперь она даже не создавать Это. Не знаете, где проблема. Каждый раз, когда я запускаю код и из второй функции, я получаю строку печати, которую файл журнала не найден. Часть перед перенаправлением вывода команды cmd работает нормально.

Я попробовал процесс строитель также ..

Я даже пробовал с процессом строитель

String plpgsql = "\""+plpgsql_path+"\" -U "+env.get("PG_USER")+" -w -h "+env.get("PG_HOST")+" -d "+env.get("PG_DB")+" -a -f "+"\""+filepath+"copy_"+tb_name+auditid+".sql\" 2> \"C:\\ER\\ETL\\psql_" +auditid +".log\""; 
ProcessBuilder pb = new ProcessBuilder("cmd.exe",plpgsql); 
Process p =pb.start(); 
p.getOutputStream().close(); 
p.waitFor(); 

ответ

1

Я ожидаю, что проблема заключается в том, что Runtime.getRuntime().exec(plpgsql) раскалывается командной строки в аргументы неправильно. В принципе, exec не понимает цитирование. Вместо этого он разбивается везде, где видит одно или несколько пробелов ... даже если эти пробелы находятся в кавычках.

Решение заключается в использовании перегрузки exec(String[]) и передачи каждого отдельного аргумента в виде отдельной строки; например

.exec(new String[]{plpgsql_path, 
        "-U", 
        env.get("PG_USER"), 
        "-w, 
        "-h", 
        // etcetera 
        }); 

UPDATE

Я не заметил, что вы использовали > перенаправление вывода, а также .

Это не работает с exec. (И то же самое относится к всем синтаксисам оболочки.) Чтобы получить перенаправление, вам необходимо использовать ProcessBuilder и один из методов redirect.

Другой вариант - запустить команду в оболочке. Передайте команду как строку и пусть оболочка позаботится о обработке цитаты, замене переменных окружения, globbing, redirection ... и так далее.

Например (если вы работаете на UNIX, Linux или MacOSX):

.exec(new String[]{"/bin/sh", "-c", plpgsql}); 

для Windows

.exec(new String[]{"cmd.exe", "/C", plpgsql}); 

Обратите внимание на опцию "/ C" в случае ОС Windows!


1 - поделом за не выравнивают авангардными, что ~ линии 200 символов в исходном коде! «SQL» Проверьте, что стандарты кодирования Java говорят о длинах линии исток ...

+0

я пробовал, но не показался работать .... Строка файл = путь_к_файл + «копия _» + tb_name + auditid +; String psqllog_file = "C: \\ ER \\ ETL \\ logs \\ psql_" + auditid + ". Log"; Процесс р = Runtime.getRuntime(). Exec (новая строка [] {plpgsql_path, "-U", env.get ("pg_user"), "-w", "-h", ENV .get ("PG_HOST"), "-d", env.get ("PG_DB"), "-a", "-f", имя файла, "> 2", psqllog_file }) ; –

+0

Я также попытался использовать построитель процессов ... –

+0

Я также обновил свой вопрос с помощью части процесса. –

Смежные вопросы