Need help in WildcardFileFilter in java - java

I have to separate out those files from a folder which matches one of the given pattern. I have an array of strings which contains these patterns. And I am passing this array as argument into WildCardFilter so that I can separate out thse files which matches the given pattern in the array. My code is given below.
String pat1="DailyExistingBusinessReport_*";
String pat2="*DailyNewExistingBusinessReport_.csv";
String pat3="*_EOD_PNL_Explained.*";
String pat4="ABC*XYZ.csv";
String str[]=new String[]{pat1,pat2,pat3,pat4};
FileFilter fileFilter = new WildcardFileFilter(str);
File dir = new File("\\C:\\Users\\ABC\\Desktop\\Myfiles");
File[] files = dir.listFiles(fileFilter);
for(File f :files){
System.out.println(f);
}
This prints out the name of files which matches the patterns given in array. But now my requirement is that alongwith each file name, I want the exact name of pattern to which this file matched. Any idea what code should I add further to get pattern name alongwith file name.

I've checked the API and don't see the way to do that with the FileFilter.
I suggest creating a list of filters and apply them one by one:
List<FileFilter> filters = new ArrayList<FileFilter>();
filters.add(new WildCardFileFilter("DailyExistingBusinessReport_*");
filters.add(new WildCardFileFilter("*DailyNewExistingBusinessReport_.csv");
filters.add(new WildCardFileFilter("*_EOD_PNL_Explained.*");
filters.add(new WildCardFileFilter("ABC*XYZ.csv");
File dir = new File("\\C:\\Users\\ABC\\Desktop\\Myfiles");
Map<FileFilter, List<File>> filemap = new HashMap<FileFilter, List<File>>();
for (File file: dir.listFiles()){
for(FileFilter filter: filters){
if(filter.accept(file)){
if(!filemap.containsKey(filter)){
filemap.put(filter, new ArrayList<File>());
}
filemap.get(filter).add(file);
}
}
}
After that, you should have a map which contain filters and lists of files for which the filter apply.
I don't have IDE by hand, so there may be some small mistakes.

Related

using java.nio.file adding the arraylist to the file

What method can be used to add arraylist to the file using java.nio.file ?
Previously I could be using
List<String> outputData = new ArrayList<String>();
//Output arraylist containing concatenated data
writeLines(File outputFile,outputData); //The data is written to file
now if i want to utilize nio library what do i do?
Path outputFile= Paths.get("outputFile");
List<String> outputData = new ArrayList<String>();
//???How to put the list in the file?

Adding String ArrayList into properties File java?

Is it possible to store a String ArrayList into a properties file and then read and modify the list in a simple way?
I think i will need to run example:
Properties p = new Properties();
File f = new File("MyText.txt");
FileInputStream in = new FileInputStream(f,"");
p.load(in);
ArrayList<String> list = p.getProperty("list");
<-- Modify the list and then open a OutputStream and save the p object again ?
Is this possible to manage easily in Java?
You can use a delimiter, say '|', to join the Strings in your ArrayList. When saving your list, use this code (String.join() needs Java 8):
String listAsString = String.join("|", list);
properties.put("list", listAsString);
When retrieving the list, do this:
List<String> list = Arrays.asList(properties.get("list").toString().split("\\|"));

Get the newest file based on timestamp in Java

I have a directory which contains files in the following format. The files are in a diretory called /incoming/external/data
ABC_20100806.csv
ABC_20100807.csv
ABC_20100808.csv
ABC_20100809.csv
ABC_20100810.csv
ABC_20100811.csv
ABC_20100812.csv
As you can see the filename of the file includes a timestamp. i.e. [RANGE]_[YYYYMMDD].csv
What i need to do is find out which of these files has the newest date using the timestamp on the filename not the system timestamp and store the filename in a variable and move it to another directory and move the rest to a different directory in java.
You can read the filenames into an array using:
File directory = new File("/incoming/external/data");
String[] fileNames = directory.list(new FilenameFilter() {
public boolean accept(File dir, String fileName) {
return fileName.endsWith(".csv");
}
});
And from there simply sort the array if your files always have the same prefix:
Arrays.sort(fileNames);
One way you can remove the prefix and suffix of each fileName to extract the date is:
int underline = fileName.indexOf("_");
int dot = fileName.indexOf(".");
String datePart = fileName.substring(underline, dot);
And then you can add that string to an array and sort (lexically).
If for some other reason you want to convert the dates into Java Dates, you can use:
SimpleDateFormat dt = new SimpleDateFormat("yyyymmdd");
Date date = dt.parse(datepart);
And you'll have a Java date, which you can also sort in an array or list.

java data structure to replace file io

My program goes to a my uni results page, finds all the links and saves to a file. Then I read the file and copy only lines which contain required links and save it to another file. Then I parse it again to extract required data
public class net {
public static void main(String[] args) throws Exception {
Document doc = Jsoup.connect("http://jntuconnect.net/results_archive/").get();
Elements links = doc.select("a");
File f1 = new File("flink.txt");
File f2 = new File("rlink.txt");
//write extracted links to f1 file
FileUtils.writeLines(f1, links);
// store each link from f1 file in string list
List<String> linklist = FileUtils.readLines(f1);
// second string list to store only required link elements
List<String> rlinklist = new ArrayList<String>();
// loop which finds required links and stores in rlinklist
for(String elem : linklist){
if(elem.contains("B.Tech") && (elem.contains("R07")||elem.contains("R09"))){
rlinklist.add(elem);
}
}
//store required links in f2 file
FileUtils.writeLines(f2, rlinklist);
// parse links from f2 file
Document rdoc = Jsoup.parse(f2, null);
Elements rlinks = rdoc.select("a");
// for storing hrefs and link text
List<String> rhref = new ArrayList<String>();
List<String> rtext = new ArrayList<String>();
for(Element rlink : rlinks){
rhref.add(rlink.attr("href"));
rtext.add(rlink.text());
}
}// end main
}
I don't want to create files to do this. Is there a better way to get hrefs and link texts of only specific urls without creating files?
It uses Apache commons fileutils, jsoup
Here's how you can get rid of the first file write/read:
Elements links = doc.select("a");
List<String> linklist = new ArrayList<String>();
for (Element elt : links) {
linklist.add(elt.toString());
}
The second round trip, if I understand the code, is intended to extract the links that meet a certain test. You can just do that in memory using the same technique.
I see you're relying on Jsoup.parse to extract the href and link text from the selected links. You can do that in memory by writing the selected nodes to a StringBuffer, convert it to a String by calling it's toString() method, and then using one of the Jsoup.parse methods that takes a String instead of a File argument.

Generating a canonical path

Does any one know of any Java libraries I could use to generate canonical paths (basically remove back-references).
I need something that will do the following:
Raw Path -> Canonical Path
/../foo/ -> /foo
/foo/ -> /foo
/../../../ -> /
/./foo/./ -> /foo
//foo//bar -> /foo/bar
//foo/../bar -> /bar
etc...
At the moment I lazily rely on using:
new File("/", path).getCanonicalPath();
But this resolves the path against the actual file system, and is synchronised.
java.lang.Thread.State: BLOCKED (on object monitor)
at java.io.ExpiringCache.get(ExpiringCache.java:55)
- waiting to lock <0x93a0d180> (a java.io.ExpiringCache)
at java.io.UnixFileSystem.canonicalize(UnixFileSystem.java:137)
at java.io.File.getCanonicalPath(File.java:559)
The paths that I am canonicalising do not exist on my file system, so just the logic of the method will do me fine, thus not requiring any synchronisation. I'm hoping for a well tested library rather than having to write my own.
I think you can use the URI class to do this; e.g. if the path contains no characters that need escaping in a URI path component, you can do this.
String normalized = new URI(path).normalize().getPath();
If the path contains (or might contain) characters that need escaping, the multi-argument constructors will escape the path argument, and you can provide null for the other arguments.
Notes:
The above normalizes a file path by treating it as a relative URI. If you want to normalize an entire URI ... including the (optional) scheme, authority, and other components, don't call getPath()!
URI normalization does not involve looking at the file system as File canonicalization does. But the flip side is that normalization behaves differently to canonicalization when there are symbolic links in the path.
Using Apache Commons IO (a well-known and well-tested library)
public static String normalize(String filename)
will do exactly what you're looking for.
Example:
String result = FilenameUtils.normalize(myFile.getAbsolutePath());
If you don't need path canonization but only normalization, in Java 7 you can use java.nio.file.Path.normalize method.
According to http://docs.oracle.com/javase/7/docs/api/java/nio/file/Path.html:
This method does not access the file system; the path may not locate a file that exists.
If you work with File object you can use something like this:
file.toPath().normalize().toFile()
You could try an algorithm like this:
String collapsePath(String path) {
/* Split into directory parts */
String[] directories = path.split("/");
String[] newDirectories = new String[directories.length];
int i, j = 0;
for (i=0; i<directories.length; i++) {
/* Ignore the previous directory if it is a double dot */
if (directories[i].equals("..") && j > 0)
newDirectories[j--] = "";
/* Completely ignore single dots */
else if (! directories[i].equals("."))
newDirectories[j++] = directories[i];
}
/* Ah, what I would give for String.join() */
String newPath = new String();
for (i=0; i < j; i++)
newPath = newPath + "/" + newDirectories[i];
return newPath;
}
It isn't perfect; it's linear over the number of directories but does make a copy in memory.
Which kind of path is qualified as a Canonical Path is OS dependent.
That's why Java need to check it on the filesystem.
So there's no simple logic to test the path without knowing the OS.
So, while normalizing can do the trick, here is a procedure that exposes a little more of the Java API than would simply calling Paths.normalize()
Say I want to find a file that is not in my current directory on the file system.
My working code file is
myproject/src/JavaCode.java
Located in myproject/src/. My file is in
../../data/myfile.txt
I'm testing my program running my code from JavaCode.java
public static void main(String[] args) {
findFile("../../data","myfile.txt");
System.out.println("Found it.");
}
public static File findFile(String inputPath, String inputFile) {
File dataDir = new File("").getAbsoluteFile(); // points dataDir to working directory
String delimiters = "" + '\\' + '/'; // dealing with different system separators
StringTokenizer st = new StringTokenizer(inputPath, delimiters);
while(st.hasMoreTokens()) {
String s = st.nextToken();
if(s.trim().isEmpty() || s.equals("."))
continue;
else if(s.equals(".."))
dataDir = dataDir.getParentFile();
else {
dataDir = new File(dataDir, s);
if(!dataDir.exists())
throw new RuntimeException("Data folder does not exist.");
}
}
return new File(dataDir, inputFile);
}
Having placed a file at the specified location, this should print "Found it."
I'm assuming you have strings and you want strings, and you have Java 7 available now, and your default file system uses '/' as a path separator, so try:
String output = FileSystems.getDefault().getPath(input).normalize().toString();
You can try this out with:
/**
* Input Output
* /../foo/ -> /foo
* /foo/ -> /foo
* /../../../ -> /
* /./foo/./ -> /foo
* //foo//bar -> /foo/bar
* //foo/../bar -> /bar
*/
#Test
public void testNormalizedPath() throws URISyntaxException, IOException {
String[] in = new String[]{"/../foo/", "/foo/", "/../../../", "/./foo/./",
"//foo/bar", "//foo/../bar", "/", "/foo"};
String[] ex = new String[]{"/foo", "/foo", "/", "/foo", "/foo/bar", "/bar", "/", "/foo"};
FileSystem fs = FileSystems.getDefault();
for (int i = 0; i < in.length; i++) {
assertEquals(ex[i], fs.getPath(in[i]).normalize().toString());
}
}

Categories