31

How do I remove the file name from a URL or String?

String os = System.getProperty("os.name").toLowerCase();
        String nativeDir = Game.class.getProtectionDomain().getCodeSource().getLocation().getFile().toString();

        //Remove the <name>.jar from the string
        if(nativeDir.endsWith(".jar"))
            nativeDir = nativeDir.substring(0, nativeDir.lastIndexOf("/"));

        //Load the right native files
        for(File f : (new File(nativeDir + File.separator + "lib" + File.separator + "native")).listFiles()){
            if(f.isDirectory() && os.contains(f.getName().toLowerCase())){
                System.setProperty("org.lwjgl.librarypath", f.getAbsolutePath()); break;
            }
        }

That's what I have right now, and it work. From what I know, because I use "/" it will only work for windows. I want to make it platform independent

Not a bug
  • 4,286
  • 2
  • 40
  • 80
Yemto
  • 613
  • 1
  • 7
  • 18

9 Answers9

26

Consider using org.apache.commons.io.FilenameUtils

You can extract the base path, file name, extensions etc with any flavor of file separator:

String url = "C:\\windows\\system32\\cmd.exe";

String baseUrl = FilenameUtils.getPath(url);
String myFile = FilenameUtils.getBaseName(url)
                + "." + FilenameUtils.getExtension(url);

System.out.println(baseUrl);
System.out.println(myFile);

Gives,

windows\system32\
cmd.exe

With url; String url = "C:/windows/system32/cmd.exe";

It would give;

windows/system32/
cmd.exe
StoopidDonut
  • 8,547
  • 2
  • 33
  • 51
22

By utilizing java.nio.file; (afaik introduced after J2SE 1.7) this simply solved my problem:

Path path = Paths.get(fileNameWithFullPath);
String directory = path.getParent().toString();
saygley
  • 430
  • 7
  • 12
  • 2
    Doesn't work well for HTTP URLs, which wasn't specifically mentioned in the question, but might be of interest to some browsing these answers. – Nate Jan 04 '19 at 04:40
15

You are using File.separator in another line. Why not using it also for your lastIndexOf()?

nativeDir = nativeDir.substring(0, nativeDir.lastIndexOf(File.separator));
Dirk Fauth
  • 4,128
  • 2
  • 13
  • 23
  • Because It returns the wrong thing for my system. But it don't seam to care if it becomes C:\something\something\something/something – Yemto Feb 17 '14 at 12:46
  • The File.separator is returning the file separator dependent to your system. So on Windows you will get "\" while on Unix you get "/". That's why you should use the File.separator. – Dirk Fauth Feb 17 '14 at 12:50
  • `Game.class.getProtectionDomain().getCodeSource().getLocation().getFile().toString()` returns **D:/Dropbox/NetBeansProjects/** while `System.out.println(File.separator)` returns \ so that's wrong. I have windows 7 64bit – Yemto Feb 17 '14 at 13:40
  • Well if that method always returns "/" you might want to perform a replacement first to ensure the same state in any case. String.replace() might help – Dirk Fauth Feb 18 '14 at 13:24
  • Notice that in order to get the **filename**, expression should be something like `nativeDir.substring(nativeDir.lastIndexOf(File.separator) + 1)` (so the substring *from* the separator, *to* the end). – rsenna Nov 25 '19 at 14:38
6
File file = new File(path);
String pathWithoutFileName = file.getParent();

where path could be "C:\Users\userName\Desktop\file.txt"

Zoe Lubanza
  • 164
  • 2
  • 2
3

The standard library can handle this as of Java 7

Path pathOnly;

if (file.getNameCount() > 0) {
  pathOnly = file.subpath(0, file.getNameCount() - 1);
} else {
  pathOnly = file;
}

fileFunction.accept(pathOnly, file.getFileName());
Andrew
  • 5,839
  • 1
  • 51
  • 72
Jeremy Sigrist
  • 325
  • 2
  • 11
  • 1
    path.getNameCount() documentation says: "the number of elements in the path, or 0 if this path only represents a root component" This could cause issues... – Andrew Jul 13 '17 at 19:53
1

Kotlin solution:

val file = File( "/folder1/folder2/folder3/readme.txt")
val pathOnly = file.absolutePath.substringBeforeLast( File.separator )
println( pathOnly )

produces this result:

/folder1/folder2/folder3

Interkot
  • 697
  • 8
  • 10
0

Instead of "/", use File.separator. It is either / or \, depending on the platform. If this is not solving your issue, then use FileSystem.getSeparator(): you can pass different filesystems, instead of the default.

Chthonic Project
  • 8,216
  • 1
  • 43
  • 92
  • 1
    I would. But File.separator return a "\" while nativeDir uses "/" – Yemto Feb 17 '14 at 12:38
  • Then shouldn't something like this work? `if(nativeDir.endsWith(".jar")){ int index = Math.max(nativeDir.lastIndexOf("/"), nativeDir.lastIndexOf("\\")); nativeDir = nativeDir.substring(0, index); }` – Yemto Feb 17 '14 at 12:43
  • Added more info. That should resolve the difference with native dir. – Chthonic Project Feb 17 '14 at 12:49
0

I solve this problem using regex.

For windows:

String path = "";
String filename = "d:\\folder1\\subfolder11\\file.ext";
String regEx4Win = "\\\\(?=[^\\\\]+$)";
String[] tokens = filename.split(regEx4Win);
if (tokens.length > 0)
   path = tokens[0]; // path -> d:\folder1\subfolder11
-1

Please try below code:

file.getPath().replace(file.getName(), "");
Shalu T D
  • 3,921
  • 2
  • 26
  • 37
Amin Arab
  • 530
  • 4
  • 19
  • 1
    Breaks if any directory has the same name as the target file. Since files without an extension are fine from an OS point of view, this may lead to something like: `C:\A\B\C\B` being changed to `C:\A\\C`, so you have unintentionally lost a directory. – Koenigsberg Oct 17 '22 at 09:24