Java如何分割路径?

12

这是作为字符串的输入:

"C:\jdk1.6.0\bin\program1.java"

我需要输出:

Path-->C:\jdk1.6.0\bin\
file--->program1.java
extension--->.java

注意反斜杠字符“\”。我很容易输出“/”。


2
你目前有什么代码? - Adam Paynter
根据您对@Kurt解决方案的评论,这是一项作业。请随意删除此标签。 - Stan Kurilin
这不是作业。我使用indexOf()和subString()进行了分割。我只是想知道为什么我们不能使用split()来分割它...?我还没有得到答案。 - yuvaraj
@yuvaraj,不,我应该为错误的建议道歉) - Stan Kurilin
4个回答

21

File类提供了您所需的一切:

    File f = new File("C:\\jdk1.6.0\\bin\\program1.java");
    System.out.println("Path-->" + f.getParent());
    System.out.println("file--->" + f.getName());       
    int idx = f.getName().lastIndexOf('.');
    System.out.println("extension--->" + ((idx > 0) ? f.getName().substring(idx) : "") );

编辑:感谢Dave指出,如果File.getName不包含'.',String.lastIndexOf将返回-1。


3
如果您试图限制自己使用String.split,那么请注意Kurt如何使用lastIndexOf() - John Giotta
1
创建一个文件对象f,其路径为"C:\jdk1.6.0\doc\readme"。请问这段代码的作用是什么? - Dave Jarvis
失败了。String.lastIndexOf会返回-1;-) - user473395
你的回答非常有帮助。很抱歉再次问这个问题,为什么我们不能使用string.split(regex r)来分割它呢? - yuvaraj
但这可能是一种完全低效的方法。考虑这样一个场景,当您遍历循环时,每次都会泄漏一个文件对象。 我可能是错的。欢迎任何建议。 - Hikmat Khan

9

也许你是对的。我想知道的是,为什么我们不能使用String.split()来分割它呢? - yuvaraj
就我个人而言,我倾向于对实用类持谨慎态度;它们让人感觉更像是函数式编程,而不是面向对象编程。Apache Commons包应该直接扩展File以增强其行为,正如我所展示的那样。 - Dave Jarvis
1
@Dave Jarvis:我无法否认它是一个功能性API,最终取决于个人口味。对我来说,重点在于可维护性的好处而不是API实现。 - Rhysyngsun
1
@yuvaraj:没有什么能阻止你使用String.split(),但正如Dave Jarvis在上面回复你的帖子中所说,这是一种相当有限和疯狂的方法。本页上的任何其他解决方案都更具可行性和可维护性。 - Rhysyngsun
1
我希望我能点赞两次!你刚刚节省了我大约30分钟的时间!在这种情况下,我不同意戴夫的看法。在这里,一个实用类比扩展类更有意义。想象一下,如果Apache为实用程序目的扩展了File,而另一家公司也为实用程序目的扩展了File,但是您需要访问这些实用程序类的功能。您将不得不危险地将Apache File转换回java.lang.File,以便使用来自其他公司的File实用程序类的功能。反之亦然,如果您随后需要再次获取一些Apache小工具。 - John Fitzpatrick

3

如果路径(如果是通过编程方式生成的)返回了双斜杠,则需要进行补偿。

//Considering that strPath holds the Path String
String[] strPathParts = strPath.split("\\\\");

//Now to check Windows Drive
System.out.println("Drive Name : "+strPathParts[0]);

3

由于Java的File类不支持探测文件扩展名,我建议您创建一个File的子类来提供这个功能:

package mypackage;

/**
 * Enhances java.io.File functionality by adding extension awareness.
 */
public class File extends java.io.File {
  /**
   * Returns the characters after the last period.
   *
   * @return An empty string if there is no extension.
   */    
  public String getExtension() {
    String name = getName();
    String result = "";
    int index = name.lastIndexOf( '.' );

    if( index > 0 ) {
      result = name.substring( index );
    }

    return result;
  }
}

现在只需将您的文件版本替换为Java版本即可,与Kurt的答案结合使用,即可获得所需的一切。

请注意,使用子类是理想的,因为如果您想要更改行为(由于不同操作系统使用不同的扩展分隔符令牌),则只需更新单个方法,整个应用程序就可以继续工作。(或者如果您需要修复错误,例如尝试执行str.substring(-1)。)

换句话说,如果您在代码库中的多个位置提取文件扩展名,则犯了一个错误。

进一步说,如果您想要完全抽象文件类型的知识(因为某些操作系统可能不使用.分隔符),则可以编写:

/**
 * Enhances java.io.File functionality by adding extension awareness.
 */
public class File extends java.io.File {
  public File( String filename ) {
    super( filename );
  }

  /**
   * Returns true if the file type matches the given type.
   */
  public boolean isType( String type ) {
    return getExtension().equals( type );
  }

  /**
   * Returns the characters after the last period.
   *
   * @return An empty string if there is no extension.
   */    
  private String getExtension() {
    String name = getName();
    String result = "";
    int index = name.lastIndexOf( '.' );

    if( index > 0 ) {
      result = name.substring( index );
    }

    return result;
  }
}

我认为这是一种更加强大的解决方案。这将无缝地允许替换更高级的文件类型检测机制(通过分析文件内容来确定类型),而无需改变调用代码。例如:
File file = new File( "myfile.txt" );
if( file.isType( "png" ) ) {
  System.out.println( "PNG image found!" );
}

如果用户将“myfile.png”保存为“myfile.txt”,该图像仍将被处理,因为高级版本(此处未显示)将查找在(网络)世界中启动每个单独的PNG文件的“PNG”标记。

也许你是对的。我想知道的是为什么我们不能使用String.split()来分割它呢? - yuvaraj
我无法使用 "\" 作为分隔符,使用 String.split() 来分割字符串。整个字符串返回到数组的第一个元素。我不知道为什么...你能写一下代码吗? - yuvaraj
@yuvaraj:我的意思是String.split()不是编写此功能的正确方法。你真的应该使用已经提到的indexOf() - Dave Jarvis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接