Remove some folders from the file.getpath() Java - java

So for example our file.getPath() returns "Data\Cache\Character\images\1.png"
Now what I want to do.. is to make String or another path or something to be: "Character\images\1.png" So removing those 2 first folders from the beginning. Thank you.

You can do this using the Path API very easily:
final Path image = Paths.get("/", "Data", "Cache", "Character", "images", "1.png");
final Path base = Paths.get("/", "Data", "Cache");
System.out.println(image);
System.out.println(base);
final Path relativeImage = base.relativize(image);
System.out.println(relativeImage);
Output:
\\Data\Cache\Character\images\1.png
\\Data\Cache\
Character\images\1.png

Related

Retrieve last level directory name from path

I have a string that represents a path ... something like this:
/A/B/C/D/E/{id}/{file_name}.ext
The path structure could be different but in general I would like to retrieve last directory name (in the example {id}) before the file-name.
I would like to use Path java class.
Is there a simple and safe way to retrieve last directory name using Path class?
Path#getParent returns a path’s parent. You can then use Path#getFileName:
path.getParent().getFileName();
You could use getName() with File which is available
Reference : https://docs.oracle.com/javase/6/docs/api/java/io/File.html#getName%28%29
File f = new File("C:\\Dummy\\Folder\\MyFile.PDF");
System.out.println(f.getName());
Which returns you MyFile.PDF.
(or)
// Path object
Path path
= Paths.get("D:\\eclipse\\configuration"
+ "\\myconfiguration.conf");
// call getName(int i) to get
// the element at index i
Path indexpath = path.getName(path.getNameCount()-2);
// prints the name
System.out.println("Name of the file : " + indexpath);
Which prints myconfiguration.conf. Hope it helps !

How to search file inside a specific folder in google API v3

As i am using v3 of google api,So instead of using parent and chidren list i have to use fileList, So now i want to search list of file inside a specific folder.
So someone can suggest me what to do?
Here is the code i am using to search the file :
private String searchFile(String mimeType,String fileName) throws IOException{
Drive driveService = getDriveService();
String fileId = null;
String pageToken = null;
do {
FileList result = driveService.files().list()
.setQ(mimeType)
.setSpaces("drive")
.setFields("nextPageToken, files(id, name)")
.setPageToken(pageToken)
.execute();
for(File f: result.getFiles()) {
System.out.printf("Found file: %s (%s)\n",
f.getName(), f.getId());
if(f.getName().equals(fileName)){
//fileFlag++;
fileId = f.getId();
}
}
pageToken = result.getNextPageToken();
} while (pageToken != null);
return fileId;
}
But in this method it giving me all the files that are generated which i don't want.I want to create a FileList which will give file inside a specific folder.
It is now possible to do it with the term parents in q parameter in drives:list. For example, if you want to find all spreadsheets in a folder with id folder_id you can do so using the following q parameter (I am using python in my example):
q="mimeType='application/vnd.google-apps.spreadsheet' and parents in '{}'".format(folder_id)
Remember that you should find out the id of the folder files inside of which you are looking for. You can do this using the same drives:list.
More information on drives:list method can be seen here, and you can read more about other terms you can put to q parameter here.
To search in a specific directory you have to specify the following:
q : name = '2021' and mimeType = 'application/vnd.google-apps.folder' and '1fJ9TFZOe8G9PUMfC2Ts06sRnEPJQo7zG' in parents
This examples search a folder called "2021" into folder with 1fJ9TFZOe8G9PUMfC2Ts06sRnEPJQo7zG
In my case, I'm writing a code in c++ and the request url would be:
string url = "https://www.googleapis.com/drive/v3/files?q=name+%3d+%272021%27+and+mimeType+%3d+%27application/vnd.google-apps.folder%27+and+trashed+%3d+false+and+%271fJ9TFZOe8G9PUMfC2Ts06sRnEPJQo7zG%27+in+parents";
Searching files by folder name is not yet supported. It's been requested in this google forum but so far, nothing yet. However, try to look for other alternative search filters available in Search for Files.
Be creative. For example make sure the files within a certain folder contains a unique keyword which you can then query using
fullText contains 'my_unique_keyword'
You can use this method to search the files from google drive:
Files.List request = this.driveService.files().list();
noOfRecords = 100;
request.setPageSize(noOfRecords);
request.setPageToken(nextPageToken);
String searchQuery = "(name contains 'Hello')";
if (StringUtils.isNotBlank(searchQuery)) {
request.setQ(searchQuery);
}
request.execute();

How to read file from src/main/resources with annotation processor?

I have a simple annotation processor that needs to read a configuration file from the same project as the annotated classes. Example structure:
- myproject
- src
- main
- java
- my.package.SourceFile
- resources
- config.json
In the annotation processor, I try to read the file:
FileObject resource = processingEnv.getFiler().getResource(StandardLocation.SOURCE_PATH, "", "config.json");
but it throws FileNotFoundException. I also tried other paths, such as ../resources/config.json, (which throws Invalid relative name: ../resources/config.json). And I tried putting the config file in src/main/java (and even src/main/java/my/package) instead, which I don't like, but that also still throws FileNotFoundException.
It would already help if I could get filer.getResource() to tell me where it's looking. To find that out, I tried generating a file:
filer.createResource(StandardLocation.SOURCE_OUTPUT, "", "dummy");
which generated in myproject/build/classes/main/dummy. Unfortunately, I can't generate in SOURCE_PATH, so that doesn't help with finding this out.
I'd expect that the stuff from src/main/resources gets copied to target/classes during the build (prior to annotation processing). In that case you can open them like this:
ProcessingEnvironment pe = ...;
FileObject fileObject = pe.getFiler()
.getResource( StandardLocation.CLASS_OUTPUT, "", "config.json" );
InputStream jsonStream = fileObject.openInputStream();
I've looked at this with one of the Project Lombok developers. If anyone knows annotation processing, it's them ;)
Our conclusion was, that the JavacFileManager that handles the request internally, does not have a path to resolve StandardLocation.SOURCE_PATH to. We're not sure, but it might be related to building with Gradle.
I had the same problem and was searching for solution for a while and found this cool hack that does the trick for Android
And below you can see my solution from pure Java/Kotlin project
fun ProcessingEnvironment.getResourcesDirectory(): File {
val dummySourceFile = filer.createSourceFile("dummy" + System.currentTimeMillis())
var dummySourceFilePath = dummySourceFile.toUri().toString()
if (dummySourceFilePath.startsWith("file:")) {
if (!dummySourceFilePath.startsWith("file://")) {
dummySourceFilePath = "file://" + dummySourceFilePath.substring("file:".length)
}
} else {
dummySourceFilePath = "file://$dummySourceFilePath"
}
val cleanURI = URI(dummySourceFilePath)
val dummyFile = File(cleanURI)
val projectRoot = dummyFile.parentFile.parentFile.parentFile.parentFile.parentFile
return File(projectRoot.absolutePath + "/resources")
}
Following function works for me with annotation processor being triggered by gradle, it's not the pretties one but works:
private fun resolveApplicationPropertiesFile(): File {
val projectRoot = Path.of(processingEnv.filer.getResource(StandardLocation.CLASS_OUTPUT, "", "doesntmatter")
.toUri())
.parent
.parent
.parent
.parent
.parent
.parent
val properties = Path.of(projectRoot.toString(), "src", "main", "resources", "application.yml")
return properties.toFile()
}
where processingEnv is a member of AbstractProcessor
If your element is instance of TypeElement,then you can use these code to find your source code
FileObject fileObject = processingEnv.getFiler().getResource(
StandardLocation.SOURCE_PATH, element.getEnclosingElement().toString(),
element.getSimpleName() + ".java");
element.getEnclosingElement() is your class package, eg: com.fool
element.getSimpleName() is your class name, eg: Person
then you can print them:
CharSequence content = fileObject.getCharContent(true);

How to dynamically update absolute path

Given the below incoming path, e.g.
C:\cresttest\parent_3\child_3_1\child_3_1_.txt
How can one update and add new dir in between above path to construct below result
C:\cresttest\NEW_PATH\parent_3\child_3_1\child_3_1_.txt
Currently I am using multiple subString to identify the incoming path, but incoming path are random and dynamic. Using substring and placing my new path requires more line of code or unnecessary processing, is there any API or way to easily update and add my new dir in between the absolute path?
By using java.nio.file.Path, you could to the following:
Path incomingPath = Paths.get("C:\\cresttest\\parent_3\\child_3_1\\child_3_1_.txt");
//getting C:\cresttest\, adding NEW_PATH to it
Path subPathWithAddition = incomingPath.subpath(0, 2).resolve("NEW_PATH");
//Concatenating C:\cresttest\NEW_PATH\ with \parent_3\child_3_1\child_3_1_.txt
Path finalPath = subPathWithAddition.resolve(incomingPath.subpath(2, incomingPath.getNameCount()));
You could then get the path URI by calling finalPath.toUri()
Note: this doesn't depend on any names in your path, it depends on the directory depth though, which you could edit in the subpath calls.
Note 2: you could probably reduce the amount of Path instances you make to one, I made three to improve readability.
You may simply insert a path at the second backslash like this:
String path="C:\\cresttest\\parent_3\\child_3_1\\child_3_1_.txt";
final String slash="\\\\";
path=path.replaceFirst(slash+"[^"+slash+"]+"+slash, "$0NEW_PATH"+slash);
System.out.println(path);
Demo
This replaces the first occurrence of \\arbitrarydirname\\ with itself (referred to via $0) followed by NEWPATH\\.
The separator’s source code representation looks a bit odd ("\\\\") as a backslash has to be escaped twice when writing regular expression in a Java String literal.
If you want your operation to be platform independent, you may replace that line with
final String slash = Pattern.quote(FileSystems.getDefault().getSeparator());
Of course, then, the input path must be in the right format for the platform as well.
You can use this simple regex replace:
path = path.replaceAll(":.\\w+", "$0\\\\NEW_PATH");
Your code would be simpler if you used / instead of \ for your path delimiters. eg, compare:
String path = "C:\\cresttest\\parent_3\\child_3_1\\child_3_1_.txt";
path = path.replaceAll(":.\\w+", "$0\\\\NEW_PATH");
with
String path = "C:/cresttest/parent_3.child_3_1/child_3_1_.txt";
path = path.replaceAll(":.\\w+", "$0/NEW_PATH");
Java can handle either delimiter on windows, but on linux only / works, so to make your code portable and more readable, prefer using /.
Just for fun, not sure whether this is what you wanted
public static String addFolderToPath(String originalPath, String newFolderName, int position){
String returnString = "";
String[] pathArray = originalPath.split("\\\\");
for(int i = 0; i<pathArray.length; i++){
returnString = returnString.concat(i==position ? "\\" + newFolderName : "");
returnString = returnString.concat(i!=0 ? "\\" + pathArray[i] : "" + pathArray[i]);
}
return returnString;
}
Call:
System.out.println(addFolderToPath("c:\\abc\\def\\ghi\\jkl", "test", 1));
System.out.println(addFolderToPath("c:\\abc\\def\\ghi\\jkl", "test", 2));
System.out.println(addFolderToPath("c:\\abc\\def\\ghi\\jkl", "test", 3));
System.out.println(addFolderToPath("c:\\abc\\def\\ghi\\jkl", "test", 4));
Run:
c:\test\abc\def\ghi\jkl
c:\abc\test\def\ghi\jkl
c:\abc\def\test\ghi\jkl
c:\abc\def\ghi\test\jkl

Does groovy have an easy way to get a filename without the extension?

Say I have something like this:
new File("test").eachFile() { file->
println file.getName()
}
This prints the full filename of every file in the test directory. Is there a Groovy way to get the filename without any extension? (Or am I back in regex land?)
I believe the grooviest way would be:
file.name.lastIndexOf('.').with {it != -1 ? file.name[0..<it] : file.name}
or with a simple regexp:
file.name.replaceFirst(~/\.[^\.]+$/, '')
also there's an apache commons-io java lib for that kinda purposes, which you could easily depend on if you use maven:
org.apache.commons.io.FilenameUtils.getBaseName(file.name)
The cleanest way.
String fileWithoutExt = file.name.take(file.name.lastIndexOf('.'))
Simplest way is:
'file.name.with.dots.tgz' - ~/\.\w+$/​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
Result is:
file.name.with.dots
new File("test").eachFile() { file->
println file.getName().split("\\.")[0]
}
This works well for file names like:
foo, foo.bar
But if you have a file foo.bar.jar, then the above code prints out: foo
If you want it to print out foo.bar instead, then the following code achieves that.
new File("test").eachFile() { file->
def names = (file.name.split("\\.")
def name = names.size() > 1 ? (names - names[-1]).join('.') : names[0]
println name
}
The FilenameUtils class, which is part of the apache commons io package, has a robust solution. Example usage:
import org.apache.commons.io.FilenameUtils
String filename = '/tmp/hello-world.txt'
def fileWithoutExt = FilenameUtils.removeExtension(filename)
This isn't the groovy way, but might be helpful if you need to support lots of edge cases.
Maybe not as easy as you expected but working:
new File("test").eachFile {
println it.name.lastIndexOf('.') >= 0 ?
it.name[0 .. it.name.lastIndexOf('.')-1] :
it.name
}
As mentioned in comments, where a filename ends & an extension begins depends on the situation. In my situation, I needed to get the basename (file without path, and without extension) of the following types of files: { foo.zip, bar/foo.tgz, foo.tar.gz } => all need to produce "foo" as the filename sans extension. (Most solutions, given foo.tar.gz would produce foo.tar.)
Here's one (obvious) solution that will give you everything up to the first "."; optionally, you can get the entire extension either in pieces or (in this case) as a single remainder (splitting the filename into 2 parts). (Note: although unrelated to the task at hand, I'm also removing the path as well, by calling file.name.)
file=new File("temp/foo.tar.gz")
file.name.split("\\.", 2)[0] // => return "foo" at [0], and "tar.gz" at [1]
You can use regular expressions better.
A function like the following would do the trick:
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
}
Note
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}"
}
Some of the below solutions (except the one using apache library) doesn't work for this example - c:/test.me/firstfile
If I try to find an extension for above entry, I will get ".me/firstfile" - :(
Better approach will be to find the last occurrence of File.separator if present and then look for filename or extension.
Note:
(There is a little trick happens below. For Windows, the file separator is \. But this is a special character in regular expression and so when we use a variable containing the File.separator in the regular expression, I have to escape it. That is why I do this:
def fileSeparator= "\\" + File.separator;
Hope it makes sense :)
Try this out:
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"
// 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()

Categories