简体   繁体   中英

Reading output from Powershell takes much time to execute

So, I wrote this code on java and it's taking some 6 second times to execute and give output. As I am not from coding background I was expecting if someone from this expert's group could help me optimize this little. Below is my code also the PowerShell command runs within seconds. only this while loop is taking much time.

What I want to achieve is just get the list of drives which is HDD and print it.

Process p = Runtime.getRuntime().exec("powershell.exe Get-Partition -disknumber 1 | select DriveLetter");
BufferedReader in = new BufferedReader(new java.io.InputStreamReader(p.getInputStream()));
String line1 = "";
ArrayList<String> hddList = new ArrayList<String>();
while ((line1 = in.readLine()) != null) {
    if (!line1.trim().isEmpty()) {
        if (line1.contains("HDD")) {
            hddList.add(line1.replaceAll(" +", "#").split("#")[0]+"#"+"HDD");
        }
    }
}

As I said in my comments, I believe the issue is with the execution of the powerShell and not Java. See how quickly the following runs using the cmd.exe . Here, all I'm doing is a directory listing and replacing <DIR> as though it was HDD.

        Process p = Runtime.getRuntime().exec(
                "cmd.exe /c dir".split("\\s+"));
                        
        System.out.println(p);
        BufferedReader in = new BufferedReader(
                new java.io.InputStreamReader(p.getInputStream()));
        String line1 = "";
        List<String> hddList = new ArrayList<String>();
        while ((line1 = in.readLine()) != null) {
            System.out.println(line1);
            if (!line1.trim().isEmpty()) {
                if (line1.contains("<DIR>")) {
                    hddList.add(line1.replaceAll(" +", "#").split("#")[0] + "#"
                            + "HDD");
                }

            }
        }
        System.out.println(hddList);

You might be able to run cmd.exe as administrator and use related privileged commands to get the disk information. I have yet to determine how to do that without password input.

This seems to be an xy-problem , as you can easily get the drive letters in Java like

List<String> driveLetters = new ArrayList<>();
for(Path r: FileSystems.getDefault().getRootDirectories()) {
    String s = r.toString();
    if(s.length() == 3 && s.charAt(1) == ':') {
        driveLetters.add(s.substring(0, 1));
    }
}

since Java 7. This needs no interprocess communication and hence, has no such latency problems.

If you want to limit the result to fixed HDDs, you can use something like

List<String> driveLetters = new ArrayList<>();
for(Path r: FileSystems.getDefault().getRootDirectories()) {
    String s = r.toString();
    if(s.length() == 3 && s.charAt(1) == ':') try {
        FileStore store = Files.getFileStore(r);
        if(!Boolean.TRUE.equals(store.getAttribute("volume:isRemovable"))
        && !Boolean.TRUE.equals(store.getAttribute("volume:isCdrom"))) {
            driveLetters.add(s.substring(0, 1));
        }
    }
    catch(IOException ex) {} // no media in drive, obviously not an HDD then
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM