Java groovy有没有一种不带扩展名的简单方法来获取文件名?

Java groovy有没有一种不带扩展名的简单方法来获取文件名?,java,file-io,groovy,file-extension,Java,File Io,Groovy,File Extension,假设我有这样的东西: new File("test").eachFile() { file-> println file.getName() } 这将打印test目录中每个文件的完整文件名。有没有一种Groovy方法可以不带任何扩展名就获取文件名?(或者我回到了regex land?)也许没有你想象的那么容易,但工作: new File("test").eachFile { println it.name.lastIndexOf('.') >= 0 ? i

假设我有这样的东西:

new File("test").eachFile() { file->  
println file.getName()  
}

这将打印
test
目录中每个文件的完整文件名。有没有一种Groovy方法可以不带任何扩展名就获取文件名?(或者我回到了regex land?)

也许没有你想象的那么容易,但工作:

new File("test").eachFile { 
  println it.name.lastIndexOf('.') >= 0 ? 
     it.name[0 .. it.name.lastIndexOf('.')-1] : 
     it.name 
  }

您可以更好地使用正则表达式。 下面这样的函数可以实现此目的:

def getExtensionFromFilename(filename) {
  def returned_value = ""
  m = (filename =~ /(\.[^\.]*)$/)
  if (m.size()>0) returned_value = ((m[0][0].size()>0) ? m[0][0].substring(1).trim().toLowerCase() : "");
  return returned_value
}

我认为最好的方式是:

file.name.lastIndexOf('.').with {it != -1 ? file.name[0..<it] : file.name}
此外,还有一个apache commons io java lib可用于此目的,如果使用maven,您可以很容易地依赖它:

org.apache.commons.io.FilenameUtils.getBaseName(file.name)
这适用于以下文件名: 福,福吧

但是如果您有一个文件foo.bar.jar,那么上面的代码将打印出来:foo 如果您希望它打印出foo.bar,那么下面的代码可以实现这一点

new File("test").eachFile() { file->  
    def names = (file.name.split("\\.")
    def name = names.size() > 1 ? (names - names[-1]).join('.') : names[0]
    println name
}

正如在注释中提到的,文件名结束和扩展名开始的位置取决于具体情况。在我的情况下,我需要获取以下类型文件的基本名称(没有路径和扩展名的文件):{
foo.zip
bar/foo.tgz
foo.tar.gz
}=>都需要生成“
foo
”作为文件名扩展名。(大多数解决方案,给定
foo.tar.gz
将产生
foo.tar

这里有一个(显而易见的)解决方案,它将为您提供到第一个“.”为止的一切;或者,您可以将整个扩展名分成若干部分或(在本例中)作为单个余数(将文件名拆分为
2
部分)。(注意:虽然与手头的任务无关,但我也通过调用
file.name
删除了路径)


FilenameUtils类是apache commons io包的一部分,它有一个健壮的解决方案。用法示例:

import org.apache.commons.io.FilenameUtils

String filename = '/tmp/hello-world.txt'
def fileWithoutExt = FilenameUtils.removeExtension(filename)
这不是groovy的方式,但如果您需要支持大量边缘情况,则可能会有所帮助。

注意

import java.io.File;

def fileNames    = [ "/a/b.c/first.txt", 
                     "/b/c/second",
                     "c:\\a\\b.c\\third...",
                     "c:\\a\b\\c\\.text"
                   ]

def fileSeparator = "";

fileNames.each { 
    // You can keep the below code outside of this loop. Since my example
    // contains both windows and unix file structure, I am doing this inside the loop.
    fileSeparator= "\\" + File.separator;
    if (!it.contains(File.separator)) {
        fileSeparator    =  "\\/"
    }

    println "File extension is : ${it.find(/((?<=\.)[^\.${fileSeparator}]+)$/)}"
    it    =  it.replaceAll(/(\.([^\.${fileSeparator}]+)?)$/,"")

    println "Filename is ${it}" 
}
希望它有意义:)

试试这个:

import java.io.File;

String strFilename     =  "C:\\first.1\\second.txt";
// Few other flavors 
// strFilename = "/dd/dddd/2.dd/dio/dkljlds.dd"

def fileSeparator= "\\" + File.separator;
if (!strFilename.contains(File.separator)) {
    fileSeparator    =  "\\/"
}

def fileExtension = "";
(strFilename    =~ /((?<=\.)[^\.${fileSeparator}]+)$/).each { match,  extension -> fileExtension = extension }
println "Extension is:$fileExtension"
导入java.io.File;
String strFilename=“C:\\first.1\\second.txt”;
//很少有其他口味
//strFilename=“/dd/dddd/2.dd/dio/dkljlds.dd”
def fileSeparator=“\\”+File.separator;
如果(!strFilename.contains(File.separator)){
fileSeparator=“\\/”
}
def fileExtension=“”;
(strFilename=~/(?fileExtension=extension}
println“扩展名为:$fileExtension”
最干净的方式

String fileWithoutExt=file.name.take(file.name.lastIndexOf('.'))
最简单的方法是:

'file.name.with.dots.tgz' - ~/\.\w+$/​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
结果是:

file.name.with.dots

有时文件没有扩展名,但里面有一个
。我不知道为什么我在发布这篇文章后才看到mauro的答案。这应该是一个注释,因为它几乎相同,但没有forEach/closure。我现在就不说了,因为如果不熟悉
{file->yada-yada}
语法(这当然在原始问题中,但在其他方面与问题无关)。我也没有:)我显然提供了一个示例,说明了如何获取没有路径但带有扩展名的文件名。因此,我没有每次都回答author.apache commons的问题!“编译组:'commons io',名称:'commons io',版本:'2.6'”。在以下情况下,这绝对是它产生非直观预期结果的最干净的方式:
assert['.foobar','foobar']。collect{it.take(it.lastIndexOf('.')}=[''',]
def fileSeparator= "\\" + File.separator;
import java.io.File;

String strFilename     =  "C:\\first.1\\second.txt";
// Few other flavors 
// strFilename = "/dd/dddd/2.dd/dio/dkljlds.dd"

def fileSeparator= "\\" + File.separator;
if (!strFilename.contains(File.separator)) {
    fileSeparator    =  "\\/"
}

def fileExtension = "";
(strFilename    =~ /((?<=\.)[^\.${fileSeparator}]+)$/).each { match,  extension -> fileExtension = extension }
println "Extension is:$fileExtension"
'file.name.with.dots.tgz' - ~/\.\w+$/​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
file.name.with.dots
// Create an instance of a file (note the path is several levels deep)
File file = new File('/tmp/whatever/certificate.crt')

// To get the single fileName without the path (but with EXTENSION! so not answering the question of the author. Sorry for that...)
String fileName = file.parentFile.toURI().relativize(file.toURI()).getPath()