I have a .tar directory and inside that again .tar.gz directory and within that .gz or .tar folder/files my or may not be available.
I want to keep checking and extract this till 10 level deeper.
It means extract the .tar folder, found .tar.gz, again go on till the end and extract it.
I am able to do till 1 level using apache commons that is .tar if i am extracting, i am able to see .tar.gz file at destination folder.
My concern is how to loop in this logic to check till ten level deeper and extract it.
So your question is how to allow up to ten levels of recursion. How about this?
void unarchive(File archive, File targetDirectory) {
unarchive(File archive, File targetDirectory, 10);
}
void unarchive(File archive, File targetDirectory, int depth) {
// perform your unarchive that you have anyway
if (depth>0) {
// loop over extracted files. If you have any kind of archive, then
unarchive(foundarchive, new File(targetDirectory, foundarchive.getName()), depth-1);
}
}
Related
I am writing a utility that will search the folder and list files.
The main intention is to find all the files with same name but with diff extensions. For eg: in a given folder we have files that are a.log ,a.jpg,a.clone,b.log, c.log,d.log, d.clone and my output should be only c.log and d.log . My main intention is to find the files which contain extension of .clone and do not print them in this case files c and d do not have extension of .clone and they should be the output.
I am not able to list the files with the same name but different extensions.
Any advice on how to go about this.
Regards,
Vilas
When you list all files in some folder, for example: File[] files = file.listFiles(), you can loop through them and check the file names. Here, file is actually the folder in which you want to search for your file.
for(int i=0; i<files.length; i++)
{
if(files[i].getName().startsWith("filename."))
{
do what you want
}
}
So all files that starts with "filename." will meet the criteria, no matter what comes after the . i.e. extension.
Since Java 7 you can use the walkTreeFile() to control how deep you want to go down the tree, and what to do with each file you found (with an appropriate FileVisitor).
With an Executor you can process files without waiting for the search to be finished.
Since Java 8, you should not use FileVisitor, walkTreeFile() and File class as suggested before but you should use the interface Path and the method Files.list(Path dir) :
public static void main(String[] args) throws IOException
{
Path folderWithTheFiles = Paths.get("/my/folder/with/the/files/");
//list the folder and add files names with a .clone extension in a Set
Set<String> cloneFilesNames = Files.list(folderWithTheFiles)
.filter(p->p.toString().endsWith(".clone"))
.map(p -> p.getFileName().toString().split("\\.")[0]).collect(Collectors.toSet());
//list the folder and filter it with the Set created before
Files.list(folderWithTheFiles)
.filter(p->!cloneFilesNames.contains(p.getFileName().toString().split("\\.")[0]))
.map(Path::getFileName).forEach(System.out::println);
}
If you want to search deeper in the files tree use Files.walk(Path dir) instead of Files.list(Path dir)
I would really appreciate your input on the below scenario please.
The requirements:
- I have a 7zip archive file with several thousands of files in it
- I have a java application running on linux that is required to retrieve individual files from the 7 zip file
I would like to retrieve a file from the archive by its path (e.g. my7zFile.7z/file1.pdf) without having to iterate through all the files in the archive and comparing file names.
I would like to avoid having to extract all files from the archive before running the search (the uncompressed archive is several TB).
I had a look into 7zip Java Binding - specifically the IInArchive class, the only extract method seems to work via file index, not via file name:
http://sevenzipjbind.sourceforge.net/javadoc/net/sf/sevenzipjbinding/IInArchive.html
Do you know of any other libraries that could help me with this use case or am I overlooking a way of doing this with 7zip jbinding?
Thank you
Kind regards,
Tobi
Sadly it appears the API doesn't provide enough to fulfill all your requirements. In order to extract a single file it appears you need to walk the archive index. The simplified interface to the archive makes this much easier:
The ISimpleInArchive interface provides:
ISimpleInArchiveItem[] getArchiveItems()
Allowing you to retrieve an list of items in the archive.
The ISimpleInArchiveItem interface provides the method:
java.lang.String getPath()
Hence you can walk the archiveItems comparing on path. Granted this is against your requirements.
However, note this walks the index table and does not extract the files until requested. Once you have the item your after you can use:
ExtractOperationResult extractSlow(ISequentialOutStream SequentialOutStream)
on the item you have found to actually extract it.
Looking at the 7z file format (note this is not the official site of 7zip), the header information is all at the end of the file with the Signature header at the start of the file giving an offset to the start of the header info. So provided the SevenZip bindings are written nicely, your search will at most read the start of the file (SignatureHeader) to find the offset to the HeaderInfo section, then walk the HeaderInfo section in order to build up the file list required in getArchiveItems(). Only once you have the item you need will it shift back to the index of the actual stream for the file you want extracted (most likely when you call extractSlow).
So whilst not all your requirements are met, the overhead of the search/compare required is limited to only searching the header info of the archive.
Once I wrote a code to read from all the files and folders from a zip file. I had a long file(text)/folder hierarchy inside the zip file. I am not sure whether that will help you or not. I am sharing the skeleton of the code.
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
ZipFile zipFile = new ZipFile(filepath); // filepath of the zip file
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (entry.isDirectory()) { // found directory inside the zipFile
// write your code here
} else {
InputStream stream = zipFile.getInputStream(entry);
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
// write your code to read the content of the file
}
}
You can modify the code to reach your desired file in the zip. But i don't think you will be able to access the file directly rather you have to walk through all the paths of the zip archive. Note that, ZipFile iterates through all file and folders inside a zipped file in DFS (Depth First Search) manner. You will find detailed relevant examples in web.
I'm using Apache Commons Compress to parse entries in a 7zip archive. I need to be able to find a specific file (e.g. "thisfile.xml"), I was wondering if there is a better way of doing it other than just looping through every entry in the archive.
The sort of thing I'm currently doing is this:
SevenZFile archive = new SevenZFile("chosen 7zip file");
for (SevenZArchiveEntry entry : sevenZFile.getEntries())
{
if (entry.getName().equals("Sites.xml"))
{
//Do stuff
break;
}
}
I don't particularly want to iterate over all entries in the archive, as there could be a lot of them.
Any ideas would be much appreciated
Hello one of the parts of a program i'm working on requires the ability to search through a directory. I understand how using a path variable works and how to get to a directory; but once you are in the directory how can you distinguish files from one another? Can we make an array/or a linked list of the files contained within the directory and search using that?
In this specific program the goal is for the user to input a directory, from there go into sub-directory and find a file that ends with .mp3 and copy that to a new user created directory. It is certain that there will only be one .mp3 file in the folder.
Any help would be very much appreciated.
Seeing what you say, I will suppose that you use the java7 Path api.
To know if a path is a directory or a simple file, use Files.isDirectory(Path)
To list the files / directories in your directory, use Files.list(Path)
The javadoc of the Files class : http://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html
If you use the "old" java.io.File api, then you have a listFiles method, which can take a FileFilter as argument to filter, for exemple, only the files ending with ".mp3".
Good luck
Get Files as so:
List<String> results = new ArrayList<String>();
File[] files = new File("/path/to/the/directory").listFiles();
for (File file : files)
if (file.isFile())
results.add(file.getName());
If you want the extension:
public static String getExtension(String filename){
String extension = "";
int i = fileName.lastIndexOf('.');
if (i > 0)
extension = fileName.substring(i+1);
return extension;
}
There are other ways to get file extensions listed here but they usually require a common external library.
You can use the File object to represent your directory, and then use the listFiles() (which return an array of files File[]) to retrieve the files into that directory.
If you need to search through subdirectories, you can use listFiles() recursively for each directory you encounter.
As for the file extension, the Apache Commons IO library has a neat FileFilter for that: the SuffixFileFilter.
I have a folder in which there is a .dat file and one is .zip file ,I have to move the .zip file to another directory
I have two folders one is
1) c:\source folder --> having two files abc.dat and other is abc.zip
2) c:\destination ---> in which zip shpould be get copied
please advise how to achiev this what I have done rite now is ...
File directory = new File(sourceFolder);
File[] listFiles = (mcrpFilePath).listFiles();
for (File f : listFiles) {
if (f.isFile()) { // ?? here logic to pick up the zip file
//logic to move the zip file to other directory
}
}
Use File.renameTo
Renames the file denoted by this abstract pathname.
Many aspects of the behavior of this method are inherently platform-dependent: The rename operation might not be able to move a file from one filesystem to another, it might not be atomic, and it might not succeed if a file with the destination abstract pathname already exists. The return value should always be checked to make sure that the rename operation was successful.
Here is Example
Or you can use Files#move (if you are using java 7)
Move or rename a file to a target file.
here is Example using move()
As simple as using the method renameTo() in File class.
public boolean renameTo(File dest);
Renames the file denoted by this abstract pathname.
Get file full path and rename it to the required location.
And make use of boolean that return by that method,to know weather it's successfully moved or not.
For detecting your zip-file:
if(f.getName.equals("abc.zip"))
or for all zip files:
if(f.getName.endsWith(".zip"))
With a regex:
if(f.getName.matches("abc*\\.zip"))
For moving it:
f.renameTo(new File("C:\dest\abc.zip");
Or, more simply:
new File("C:\src\abc.zip").renameTo("C:\dest\abc.zip");
catching exceptions as needed.
Use java.io.File and its methods to get the list of .zip files and move them (Tutorial - Moving a File or Directory).
import static java.nio.file.StandardCopyOption.*;
...
Files.move(source, target, REPLACE_EXISTING);
SOURCE