FileUtils.listFiles and IOFileFilter - java

Hi i want to recursively check if the files and subfolders of a certain directory contain a certain string so tried this
package com.tecsys.sm.test;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.apache.commons.io.filefilter.TrueFileFilter;
import com.tecsys.sm.util.WindowsDirectories;
public class ApacheListOfFiles {
public static void main(String[] args){
final String envName= "test_trunkcpsm";
WindowsDirectories wd = new WindowsDirectories();
File startPath = new File(wd.getStartMenuDir()+File.separator+"Programs");
Collection<File> listF = FileUtils.listFiles(startPath, new IOFileFilter() {
#Override
public boolean accept(File dir, String name) {
return false;
}
#Override
public boolean accept(File file) {
// TODO Auto-generated method stub
if(file.getName().contains(envName)){
System.out.println(file);
return true;
}else
return false;
}
},TrueFileFilter.INSTANCE);
System.out.println(listF.size());
Iterator<File> it = listF.iterator();
while(it.hasNext()){
System.out.println("Le fichier est : "+it.next());
}
}
}
The output of this is the following:
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\TECSYS\iTopia Environments\test_trunkcpsm
0
So he finds the file i am searching for but still return an empty list, why is that ? And also while we are at it, when is the first accept called ? i have some difficulties understanding how this class works.

It works for me, may be the reason is false returned in the first accept().
You may also want to look at DelegateFileFilter to implement a single accept().
Or to use this single call for the job:
Collection listF = FileUtils.listFiles(
startPath, new WildcardFileFilter("*" + envName + "*"), TrueFileFilter.TRUE);

Related

ClassOrInterfaceDeclaration.getTokenRange() gets all the tokens for a file even after removing nodes from the class

When I remove "ClassOrInterfaceDeclaration" nodes from a class in CompilationUnit (JavaParser) from a parsed file that contains more than one class, ClassOrInterfaceDeclaration.getTokenRange() gets all the tokens even the removed nodes tokens.
For example, the code snippet at positions 1 and 2 will give the same result, although I already removed nodes from ClassOrInterfaceDeclaration n.
Does anyone know how to get the correct tokens list?
private void RemoveOtherClassesFromSameFile(ClassOrInterfaceDeclaration n) {
n.getTokenRange() // 1
List<ClassOrInterfaceDeclaration> internalClasses = unmodifiableList(
n.getMembers().stream().filter(m -> m instanceof ClassOrInterfaceDeclaration)
.map(m -> (ClassOrInterfaceDeclaration) m).collect(toList()));
for (ClassOrInterfaceDeclaration c : internalClasses)
n.remove(c);
n.getTokenRange() // 2
}
Ater Adjusting the file that contains the node, you must update the source root by using method saveAll, to override the AST to your file, like that
sourceRoot.saveAll(Paths.get(parsedFilePath));
Full Example:
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.visitor.ModifierVisitor;
import com.github.javaparser.ast.visitor.Visitable;
import com.github.javaparser.utils.SourceRoot;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) throws IOException {
Path dirPath = Paths.get("C:\\JavaParserTest\\src\\main\\resources\\src\\");
SourceRoot sourceRoot = new SourceRoot(dirPath);
sourceRoot.tryToParse();
CompilationUnit cu = sourceRoot.parse("", dirPath.toString()+"\\JavaFile.java");
cu.accept(new ModifierVisitor<Void>() {
#Override
public Visitable visit(ClassOrInterfaceDeclaration n, Void arg) {
RemoveOtherClassesFromSameFile(n, cu);
return super.visit(n, arg);
}
}, null);
sourceRoot.saveAll(Paths.get(dirPath.toString()+"\\JavaFile.java"));
}
private static ClassOrInterfaceDeclaration RemoveOtherClassesFromSameFile(ClassOrInterfaceDeclaration n, CompilationUnit cu) {
List<ClassOrInterfaceDeclaration> internalClasses = (
n.getMembers().stream().filter(m -> m instanceof ClassOrInterfaceDeclaration)
.map(m -> (ClassOrInterfaceDeclaration) m).collect(Collectors.toList()));
for (ClassOrInterfaceDeclaration c : internalClasses){
n.remove(c);
}
return n;
}
}

How do I add all the filenames under a certain folder to an arraylist using Java

I have this much so far
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Arrays;
import org.pdfbox.util.Splitter;
public class fileName {
public static void main(String args[]){
File file = new File("/Users/apple/Desktop/");
String[] directories = file.list(new FilenameFilter(){
#Override
public boolean accept(File current, String name) {
return new File(current, name).isDirectory();
}
});
System.out.println(Arrays.toString(directories));
ArrayList<String[]>SSOList = new ArrayList<String[]>();
}
}
It prints the names of all the files on my desktop but I want to add them to an arraylist. How do I do that?
It is very easy. You can use recursion as follows:
private static void read(final File folder) {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
read(fileEntry);
} else {
//Do something
}
}
}
There are quite a few ways by which you can get the filenames in an ArrayList:
Use the Arrays.asList() method:
ArrayList<String> SSOList = new ArrayList<String>(Arrays.asList(directories));
Use the Collections utility class allAll method:
List<String> SSOList = new ArrayList<String>(directories.length);
Collections.addAll(SSOList , directories);
Traverse the directories array again and add each value to the ArrayList SSOList.
Kepping in mind that these are to be done after you get the values in directories array.
ArrayList<String> SSOList = new ArrayList<String>(Arrays.asList(directories))
or you can use:
Collections.addAll(SSOList, directories);
Also if SSOList is the name of the ArrayList you want the files to be stored in, I think you need to change it to an array list of Strings and not array list of array of Strings :
List<String>SSOList = new ArrayList<String>();

How to integrate Metaphone to the spellchecker program in java-lucene?

While browsing i came up with a spellchecking program in lucene.I was interested in adding the phonetix add-on(specifically metaphone) from tangentum. Is there a way i can integrate metaphone into my program? How to integrate it?
package com.lucene.spellcheck;
import java.io.File;
import java.io.IOException;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.spell.Dictionary;
import org.apache.lucene.search.spell.PlainTextDictionary;
import org.apache.lucene.search.spell.SpellChecker;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
public class SimpleSuggestionService {
private static final String F_WORD = null;
public static void main(String[] args) throws Exception {
File dir = new File("e:/spellchecker/");
Directory directory = FSDirectory.open(dir);
SpellChecker spellChecker1 = new SpellChecker(directory);
spellChecker1.indexDictionary(
new PlainTextDictionary(new File("c:/fulldictionary00.txt")));
String wordForSuggestions = "noveil";
int suggestionsNumber = 5;
String[] suggestions = spellChecker1.
suggestSimilar(wordForSuggestions, suggestionsNumber);
if (suggestions!=null && suggestions.length>0) {
for (String word : suggestions) {
System.out.println("Did you mean:" + word);
}
}
else {
System.out.println("No suggestions found for word:"+wordForSuggestions);
}
}
}
You can pass in a custom StringDistance implementation that utilizes desired phonetic algorithms, or combines it is some way with other similarity algorithms (such as the standard LevensteinDistance. You'll just need to implement the getDistance(String, String) method in you StringDistance implementation. Perhaps something like:
public MetaphoneDistance() {
Metaphone metaphone = new Metaphone();
}
//I'm not really familiar with the library you mentioned, but I assume generateKeys performs a double metaphone?
public float getDistance(String str1, ,String str2) {
String[] keys1 = metaphone.getKeys(str1);
String[] keys2 = metaphone.getKeys(str2);
float result = 0;
if (key1[0] == key2[0] || key1[0] == key2[1]) result += .5
if (key1[1] == key2[0] || key1[1] == key2[1]) result += .5
return result;
}

Servlet does not open txt

Servlet is very good looking and reading files that have English names like hello.txt. It does not want to read files that have a Russian name, such pushkin.txt. Is anyone able to help to solve this problem?
Here is the code:
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class servlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
public static List<String> getFileNames(File directory, String extension) {
List<String> list = new ArrayList<String>();
File[] total = directory.listFiles();
for (File file : total) {
if (file.getName().endsWith(extension)) {
list.add(file.getName());
}
if (file.isDirectory()) {
List<String> tempList = getFileNames(file, extension);
list.addAll(tempList);
}
}
return list;
}
#SuppressWarnings("resource")
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
response.setContentType("text/html; charset=UTF-8");
String myName = request.getParameter("text");
List<String> files = getFileNames(new File("C:\\Users\\vany\\Desktop\\test"), "txt");
for (String string : files) {
if (myName.equals(string)) {
try {
File file = new File("C:\\Users\\vany\\Desktop\\test\\" + string);
FileReader reader = new FileReader(file);
int b;
PrintWriter writer = response.getWriter();
writer.print("<html>");
writer.print("<head>");
writer.print("<title>HelloWorld</title>");
writer.print("<body>");
writer.write("<div>");
while((b = reader.read()) != -1) {
writer.write((char) b);
}
writer.write("</div>");
writer.print("</body>");
writer.print("</html>");
}
finally {
if(reader != null) {
try{
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
}
}
The question is relevant, the problem is not solved
I thought that you have a problem whith the statements
for (String string : files) {
if (myName.equals(string)) {
I would compare in this way
for (File file: files) {
if (myName.equals(file.getName())) {
I hope that it help you.
Note: Thanks for the comments, you can try it.
Greetings
First of all I would use a debugger to check what's wrong with that code. It's quite difficult to find a bug without running the code. If you don't want to use a debugger print out all filenames found in the directory to ensure that some file names were found:
for (String string : files) {
System.out.println(string)
....
If files were found I would check whether I have rights to write to them. It might be that the application has not proper permissions to write in selected directory.
Are files "hello.txt" and pushkin.txt directly inside "C:\Users\vany\Desktop\test\" folder? Or is pushkin.txt file in another folder from "C:\Users\vany\Desktop\test\"?
Can you show us how you invoke the servlet?
If you have pushkin.txt in another folder and you invoke the servlet with something like "folder\pushkin.txt" it will not work because getFileNames() returns file names (without folder) and "myName.equals(string)" fails as "folder\pushkin.txt" is not equal to "pushkin.txt"

With a Collection of File, get a getPath() relate to specific folder

i'm using
org.apache.commons.io.FileUtils
for get all the filed PDF contained in a specified folder (and relative subfolders)
Here a simple code
import java.io.File;
import java.util.Collection;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.apache.commons.io.filefilter.TrueFileFilter;
public class FileFilterTest
{
public static void main(String[] args)
{
File ROOT_DIR = new File("C:\\PDF_Folder");
Collection<File> PDF_FILES = FileUtils.listFiles(ROOT_DIR, new IOFileFilter() {
#Override
public boolean accept(File file)
{
return file.getName().endsWith(".pdf");
}
#Override
public boolean accept(File dir, String name)
{
return name.endsWith(".pdf");
}
}, TrueFileFilter.INSTANCE);
for(File pdf : PDF_FILES)
{
System.out.println(pdf.getPath());
}
}
}
the getPath() method returns the Absolute Path like this
C:\PDF_Folder\SomeFolder\AnotherFolder\A\20120430_TT006059__0000039.pdf
C:\PDF_Folder\Folder1\A\20120430_TT006060__000003A.pdf
C:\PDF_Folder\Folder1\Folder2\Folder3\B\20120430_TT006071__000003B.pdf
C:\PDF_Folder\Folder4\20120430_TT006125__000003C.pdf
Is there a way to get only the path related to the provided Root Folder?
SomeFolder\AnotherFolder\A\20120430_TT006059__0000039.pdf
Folder1\A\20120430_TT006060__000003A.pdf
Folder1\Folder2\Folder3\B\20120430_TT006071__000003B.pdf
Folder4\20120430_TT006125__000003C.pdf
EDIT: Here the solution created by code of jsn
for(File pdf : PDF_FILES)
{
URI rootURI = ROOT_DIR.toURI();
URI fileURI = pdf.toURI();
URI relativeURI = rootURI.relativize(fileURI);
String relativePath = relativeURI.getPath();
System.out.println(relativePath);
}
Something like this maybe:
String relPath = new File(".").toURI().relativize(pdf.toURI()).getPath();
System.out.println(relPath);
Tested, this works.
One way would be to simply 'subtract' the root path from the filename:
pdf.getPath().substring(ROOT_DIR.getPath().length() + 1)
You can you something like this as well:
for(File pdf : PDF_FILES)
{
System.out.println(pdf.getParentFile().getName()
+ System.getProperty("file.separator")
+ pdf.getName());
}

Categories

Resources