2016-11-29 14 views
1

У меня есть приложение Java, которое будет использоваться как из командной строки Windows, так и из терминала Cygwin. Программа использует и управляет путями файлов. Нам очень полезно иметь переменную sep, которая будет / при запуске программы с Cygwin, но \\ при запуске программы из Windows.Быстро найти, была ли запущена Java из Windows cmd или терминала Cygwin

Глядя here, я не уверен, что это будет возможно, но я хочу спросить.

Я выложу небольшое, компилируемое приложение, которое покажет проблему через несколько минут. На данный момент, я просто скажу, что я хочу, набор функций, что-то вроде:

// in main 
... 
String sep = getSeparatorToUse(); 
... 

// member functions 
... 
private boolean wasLaunchedFromWinCmd() 
{ 
    if (<something-here-that-knows-it-was-cmd-not-cygwin>) 
    return true; 

    return false; 

}//endof: private boolean wasLaunchedFromWinCmd() 

private String getSeparatorToUse() 
{ 
    if (wasLaunchedFromWinCmd) 
    return "\\" 

    return "/" 

}//endof: private String getSeparatorToUse() 

Благодаря @Raphael_Moita. Это очень полезно, и я, скорее всего, буду использовать их в Linux-версии приложения, которое я буду использовать. @Luke_Lee, я чувствую себя немой, не осознав этого. Я думаю, что вы, возможно, решили мою проблему, пока я готовил компилируемый код. Есть еще одна проблема, когда программа запускается из пакетного скрипта - когда она загружается с именем файла из команды find. Надеюсь, что я покажу, это проиллюстрирует это.

Примеры

Все примеры, как пробеге от Cygwin.

Работы: путь, которым пользуются большинство добровольцев, только имя файла, находящегося в том же каталоге, что и код Java.

$ java FileSeparatorExample pic_4.jpg 
Here, something will be done with the file, 
C:\Users\bballdave025\Desktop\pic_4.jpg 

работы: с относительными и путей файлов пробелов в именах файлов/пути к файлу

$ java FileSeparatorExample pretty\ pictures/pic\ 1.jpg 
Here, something will be done with the file, 
C:\Users\me\Desktop\pretty pictures/pic 1.jpg 

$ java FileSeparatorExample ../pic_5.jpg 
Here, something will be done with the file, 
C:\Users\me\Desktop\../pic_5.jpg 

не работает. Иногда выход команды find придет с полным FilePath в формате Cygwin/UNIX:

$ java FileSeparatorExample /cygdrive/c/David/example/pic.jpg 
The file: 
C:\Users\bballdave025\Desktop\/cygdrive/c/David/example/pic.jpg 
doesn't exist 

компилируется кодекс

Я просто вырубка от моего оригинального кода, так что я извините, если он кажется слишком большим.

/********************************** 
* @file FileSeparatorExample.java 
**********************************/ 

// Import statements 
import java.io.File; 
import java.io.IOException; 

public class FileSeparatorExample 
{ 
    // Member variables 
    private static String sep; 


    public static void main(String[] args) 
    { 
    ////****** DOESN'T WORK AS DESIRED ******//// 
    sep = java.io.File.separator; 
    ////** I want **//// 
    // sep = getFileSeparator(); 

    String imageToLoad = null; 
    boolean argumentExists = (args != null && args.length != 0); 

    if (argumentExists) 
    { 
     boolean thereIsExactlyOneArgument = (args.length == 1); 
     if (thereIsExactlyOneArgument) 
     { 
     imageToLoad = args[0]; 
     }//endof: if (thereIsExactlyOneArgument) 
     else 
     { 
     // do some other stuff 
     } 

    }//endof: if (argumentExists) 

    String filenamePath = getFilenamePath(imageToLoad); 
    String filenameFile = getFilenameFile(imageToLoad); 

    imageToLoad = filenamePath + sep + filenameFile; 

    File f = new File(imageToLoad); 
    if (! f.exists()) 
    { 
     System.err.println("The file:"); 
     System.err.println(imageToLoad); 
     System.err.println("doesn\'t exist"); 

     System.exit(1); 

    }//endof: if (! f.exists()) 

    System.out.println("Here, something will be done with the file,"); 
    System.out.println(imageToLoad); 

    }//endof: main 


    // member methods 
    /** 
    * Separates the filename arg into: full path to directory; bare filename 
    */ 
    private static String[] splitFilename(String imageToLoad) 
    { 
    String[] fileParts = new String[2]; 

    int indexOfLastSep = imageToLoad.lastIndexOf(sep); 
    boolean fullFilenameHasSeparator = (indexOfLastSep != -1); 
    if (fullFilenameHasSeparator) 
    { 
     fileParts[0] = imageToLoad.substring(0, indexOfLastSep); 
     fileParts[1] = imageToLoad.substring(indexOfLastSep + 1); 

    }//endof: if (fullFilenameHasSeparator) 
    else 
    { 
     // Use the user's directory as the path 
     fileParts[0] = System.getProperty("user.dir"); 
     fileParts[1] = imageToLoad; 

    }//endof: if/else (fullFilenameHasSeparator) 

    return fileParts; 

    }//endof: private static String[] splitFilename(String imageToLoad) 

    /** 
    * Gives the full path to the file's directory (from the filename arg)      
    * but not the bare filename 
    */ 
    private static String getFilenamePath(String imageToLoad) 
    { 
    String[] fileParts = splitFilename(imageToLoad); 
    return fileParts[0]; 

    }//endof: private static String getFilenamePath(String imageToLoad) 


    /** 
    * Gives the bare filename (no path information) 
    */ 
    private static String getFilenameFile(String imageToLoad) 
    { 
    String[] fileParts = splitFilename(imageToLoad); 
    return fileParts[1]; 

    }//endof: private static String getFilenamePath(String imageToLoad) 

}//endof: public class FileSeparatorExample 
+0

Прежде чем кто-нибудь спросит, я знаю о 'cygpath'. Если бы я знал, что путь к файлу будет загружен с использованием пути в стиле UNIX, я мог бы использовать: 'java $ (cygpath -wp )' Это не будет работать в моем случае. Во всяком случае, это не имело бы смысла, поскольку у тех, кто будет использовать программу Cygwin, не было бы проблем, связанных с преобразованием их стиля в стиле UNIX в путь в стиле Windows. – bballdave025

+2

Вы всегда можете использовать '/'. –

ответ

2

Вам не нужно знать, какой SO находится под вашей Java. Если ваша цель состоит в том, чтобы найти правильный разделитель файлов для использования, называют это:

java.io.File.separator; 

... Во всяком случае, чтобы выяснить, какие SO ява работает над (не знаю, как Cygwin обнаруживается это), попробуйте:

boolean isWindows = System.getProperty("os.name").startsWith("win"); 
+1

Это отличные предложения. 'IsWindows' будет особенно полезен, поскольку я запускаю сам код на Linux. Одна проблема заключается в том, что 'java.io.File.separator;' возвращает '\\' даже при запуске с терминала Cygwin. Это не совсем отвечает на мой вопрос, поэтому я не выбираю его как предпочтительный ответ, но опять же, я не совсем задал свой вопрос. Спасибо! – bballdave025

+0

Я думал об этом сегодня, и вы абсолютно правы; Мне не нужно знать, какая ОС находится под моей Java. Я мог бы просто отключить '/ cygwin/c' из аргумента filename (если существует'/cygwin/c' часть.) Единственная проблема возникает, когда аргумент имени файла приходит с другого диска - возможно, общедоступный, смонтированный диск '/ cygdrive/p'. Я не упоминал об этом в своем оригинальном посте. – bballdave025

+0

Я, однако, хочу знать, с какого терминала/запускается моя Java. – bballdave025

0

Вот ответ, я пришел к выводу, что почти отвечает на мой первоначальный вопрос. Он пытается определить пусковую установку кода Java на основе аргумента имени файла. Большое спасибо @Raphael_Moita и @Luke_Lee, которые на самом деле в значительной степени решили мою проблему. Их решения не отвечали на исходный вопрос, но отчасти потому, что я не опубликовал оригинальный вопрос полностью. Как я сказал, этот ответ не отвечает на исходный вопрос полностью. Если кто-то знает полное решение, сообщите мне.

Моим решением было несколько методов. Когда они стоят, они работают только на мое дело - Cygwin на Windows. (Что они do сообщают вам, если аргумент имени файла для приложения Java совместим с запуском из Windows cmd или нет.) Я планирую опубликовать более переносимую группу методов, то есть другие операционные системы.

Уверен, что есть проблемы. Пожалуйста, укажите их мне.

// in main 
... 
sep = java.io.File.separator; // Thanks @Luke_Lee 
if (args != null && args.length != 0) 
    sep = getSeparatorToUse(args[0]); 
... 

// member functions 
... 
private boolean wasLaunchedFromWinCmd(String firstArg) 
{ 
    boolean isWindows = System.getProperty("os.name").startsWith("win"); 
    if (! isWindows) return false; // Thanks @Raphael_Moita 
    else 
    { 
    String launchDir = System.getProperty("user.dir"); 
    String rootOfLaunchDir = getRoot(launchDir); 
        // This will come back with something like "C:\" or "P:\" 

    String rootOfArgument = getRoot(firstArg); 

    if (rootOfArgument.equals("/")) 
    { 
     String cygwinBase = "/cygdrive/"; 

     char letterOfRoot = rootOfLaunchDir.charAt(0); 
        // For, e.g., "/Users/me/Desktop/pic_314.jpg" 

     if (firstArg.startsWith(cygwinBase)) 
     { 
     int charsToCut = cygwinBase.length(); 
     letterOfRoot = firstArg.substring(charsToCut, 
              charsToCut + 1); 

     }//endof: if (firstArg.startsWith(cygwinBase)) 

     System.out.println("The root directory of your argument will be:"); 
     System.out.println(Character.toUpperCase(letterOfRoot) + ":\\"); 
     System.out.println("In Cygwin, that will be:"); 
     System.out.println(cygwinBase + 
         Character.toLowerCase(letterOfRoot) + "/"); 

     return false; 
     // Not always correct, e.g. if someone in Cygwin uses 
     // $ java FileSeparatorExample "C:\pic_137.jpg" 

    }//endof: if (rootOfArgument.equals("/")) 

    return true; 

    }//endof: if/else (! isWindows) 

}//endof: private boolean wasLaunchedFromCmd() 


private String getRoot(String fileOrDir) 
{ 
    File file = new File(fileOrDir).getAbsoluteFile(); 
    File root = file.getParentFile(); 
    while (root.getParentFile() != null) 
    root = root.getParentFile(); 

    return root.toString(); 

}//endof: private String getRoot(); 


private String getSeparatorToUse(String firstArg) 
{ 
    if (wasLaunchedFromWinCmd(firstArg)) 
    return "\\" 

    return "/" 

}//endof: private String getSeparatorToUse(String firstArg) 

Части этого раствора обусловлены @Raphael_Moita и @Luke_Lee, но я также нужно ссылаться this SO post. Последнее помогло в моей конкретной ситуации, когда файлы не все размещены на диске C:\.

Примечание Я не принимаю мое решение как правильное, потому что оно не отвечает на мой первоначальный вопрос. Надеюсь, это поможет кому-то, кто отвечает на исходный вопрос.