2012-02-06 12 views
9

¿Existe una forma independiente de plataforma con Java para detectar el tipo de unidad en la que se encuentra un archivo? Básicamente estoy interesado en distinguir entre: discos duros, unidades extraíbles (como memorias USB) y redes compartidas. Las soluciones JNI/JNA no serán útiles. Java 7 se puede suponer.Java: cómo determinar el tipo de unidad en la que se encuentra un archivo?

+0

Quizás sería más fácil de resolver ¿por qué quieres saber esto? –

+2

Necesito esa información para advertir a los usuarios sobre ciertos inconvenientes del sistema de archivos subyacente: el rendimiento, la supervisión del sistema de archivos no funcionará, cosas así. – mstrap

+0

Consulte http://stackoverflow.com/questions/3542018/how-can-i-get-list-of-all-drives-but-also-get-the-corresponding-drive-type-remo/17972420#17972420 Estoy usando WMI para acceder a la información deseada. –

Respuesta

3

La clase FileSystemView de oscilación tiene algunos funcionalidad para apoyar detectar el tipo de la unidad (cf isFloppyDrive, isComputerNode). Me temo que no hay una forma estándar de detectar si una unidad está conectada a través de USB.

ideado, probado ejemplo:

import javax.swing.JFileChooser; 
import javax.swing.filechooser.FileSystemView; 
.... 
JFileChooser fc = new JFileChooser(); 
FileSystemView fsv = fc.getFileSystemView(); 
if (fsv.isFloppyDrive(new File("A:"))) // is A: a floppy drive? 

En el JDK 7 hay otra opción. No lo he usado, pero la API FileStore tiene un método type. El documentation dice que:

El formato de la cadena devuelta por este método es altamente específico de la implementación. Puede indicar, por ejemplo, el formato utilizado o si el almacén de archivos es local o remoto.

Al parecer, la manera de utilizarlo sería la siguiente:

import java.nio.*; 
.... 
for (FileStore store: FileSystems.getDefault().getFileStores()) { 
    System.out.printf("%s: %s%n", store.name(), store.type()); 
} 
+4

FileSystemView.isFloppyDrive() es implementado por algo como "path.equals (" A: \\ ")" lo que desafortunadamente no será útil. Además, no encontré útil FileStore.type(). Devuelve "NTFS" para mis recursos compartidos de red. – mstrap

+3

FileStore # type() devuelve "NTFS" para unidades de red en Windows 7, Java 7. –

+0

FileStore # type() devuelve "NTFS" para discos duros locales en Windows 10, también. – simpleuser

1

echar un vistazo en esta discusión: How can I get list of all drives but also get the corresponding drive type (removable,local disk, or cd-rom,dvd-rom... etc)?

pagan Específicamente atención en http://docs.oracle.com/javase/1.5.0/docs/api/javax/swing/filechooser/FileSystemView.html

personalmente no han utilizado este pero parece relevante. Tiene método como es isFloppyDrive.

También echa un vistazo en JSmooth

+0

FileSystemView no funcionará. JSmooth podría funcionar, aunque esperaba encontrar alguna API que se envíe con el JRE. – mstrap

4

Se podría ejecutar cmd usando Java con:

fsutil fsinfo drivetype {drive letter} 

El resultado le dará algo como esto:

C: - Fixed Drive 
D: - CD-ROM Drive 
E: - Removable Drive 
P: - Remote/Network Drive 
+3

No es independiente de la plataforma y fsutil incluso parece requerir privilegios administrativos. – mstrap

+1

Encontré este código muy útil: http://stackoverflow.com/questions/10678363/find-the-directory-for-a-filestore – MAbraham1

+0

yo también (muy útil) – philwalk

0

Aquí es una Gist cuales muestra cómo determinar esto usando net use: https://gist.github.com/digulla/31eed31c7ead29ffc7a30aaf87131def

La parte más importante del código:

public boolean isDangerous(File file) { 
     if (!IS_WINDOWS) { 
      return false; 
     } 

     // Make sure the file is absolute 
     file = file.getAbsoluteFile(); 
     String path = file.getPath(); 
//  System.out.println("Checking [" + path + "]"); 

     // UNC paths are dangerous 
     if (path.startsWith("//") 
      || path.startsWith("\\\\")) { 
      // We might want to check for \\localhost or \\127.0.0.1 which would be OK, too 
      return true; 
     } 

     String driveLetter = path.substring(0, 1); 
     String colon = path.substring(1, 2); 
     if (!":".equals(colon)) { 
      throw new IllegalArgumentException("Expected 'X:': " + path); 
     } 

     return isNetworkDrive(driveLetter); 
    } 

    /** Use the command <code>net</code> to determine what this drive is. 
    * <code>net use</code> will return an error for anything which isn't a share. 
    * 
    * <p>Another option would be <code>fsinfo</code> but my gut feeling is that 
    * <code>net</code> should be available and on the path on every installation 
    * of Windows. 
    */ 
    private boolean isNetworkDrive(String driveLetter) { 
     List<String> cmd = Arrays.asList("cmd", "/c", "net", "use", driveLetter + ":"); 

     try { 
      Process p = new ProcessBuilder(cmd) 
       .redirectErrorStream(true) 
       .start(); 

      p.getOutputStream().close(); 

      StringBuilder consoleOutput = new StringBuilder(); 

      String line; 
      try (BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()))) { 
       while ((line = in.readLine()) != null) { 
        consoleOutput.append(line).append("\r\n"); 
       } 
      } 

      int rc = p.waitFor(); 
//   System.out.println(consoleOutput); 
//   System.out.println("rc=" + rc); 
      return rc == 0; 
     } catch(Exception e) { 
      throw new IllegalStateException("Unable to run 'net use' on " + driveLetter, e); 
     } 
    } 
Cuestiones relacionadas