2

Apologies if this is not worded well..

Basically I have this line in a servlet -

FileInputStream flinp = new FileInputStream("C:\\xampp\\img\\"+empid+".jpg");

where empid is a string.

So currently I am getting files with the empid as the name, but I need to get files that have the empid ANYWHERE in the name.. so for example if my empid is 2500, I need to get the file if its called anything like -

  • 2500_Amy
  • Amy_2500
  • Amy2500
  • 2500Amy

etc.. Can anyone help with this? Is it regex I need to use and if so what do I write? Thanks

I tried this but bringing me an error -

FileInputStream flinp = new FileInputStream("C:\\xampp\\img\\"+.*?empid.*+".jpg");

EDIT -

BTW, in my jsp I have a loop with this line in it so that multiple empid's are passed to the "ReadImage" servlet and multiple images are read.. not sure if this makes my question any different but just to add it anyway -

<img src='<%=request.getContextPath()%>/ReadImages?id<%=thisemp.getEmpGid()%>'

1
  • You can't create a FileInputStream with a regex. What would it point to, a random file that matches if there's more than one? Also, regex matches are not free. You need to enumerate the files in the directory, and try to match each one with regex - then decide what to do if there are none or more than one. Commented May 28, 2020 at 12:48

4 Answers 4

2

You're going to need to use a FileVisitor and walk the filesystem hierarchy. Use the visitor and your generated regex to filter and collect a list of files that match your criteria.

https://docs.oracle.com/javase/8/docs/api/java/nio/file/FileVisitor.html

Sign up to request clarification or add additional context in comments.

1 Comment

do you have any sample code on how I'd use the FileVisitor in my servlet to then display the files (images) on a jsp? From that documentation I can't make much out it just talks about copying or deleting files..
1

A simple solution using old java IO (which I'm inferring from using FileInputStream) could be:

public static void main(String[] args) throws FileNotFoundException {
    String dirName = "c:/stuff";
    File directory = new File(dirName);
    String[] pathnames = directory.list();

    FileInputStream fis = findFirstMatching(dirName, pathnames, "38");
    if (fis != null) {
        //your code
    }
}

static FileInputStream findFirstMatching(String dirname, String[] pathnames, String empId) throws FileNotFoundException {
    for (String pathname : pathnames) {
        if (Pattern.matches(".*" + empId + ".*", pathname)) {
            return new FileInputStream(dirname + "/" + pathname);
        }
    }
    return null;
}

2 Comments

This solution has worked! Thank you - but what I'm wondering now is I noticed that you said 'old java IO' - is there a newer way I should be doing this? and will this make my app slow in the long run because eventually there will be a few hundred files to read
It's going to be ok. It's just that as there is a java.io package with blocking input/output streams, there is also a java.nio package with non-blocking channels, buffers, paths etc. The old style still works, and will serve hundreds of files easily. But go read some 'java nio vs io' stuff on google, it's fun to learn!
0

Try to find required file using Files.walk(...):

var nameRegEx = ".*" + epid + ".*.jpd";
Optional<Path> path = Files.walk(Paths.get("C:\\xampp\\img\\"))
            .filter(Files::isRegularFile)
            .filter(p -> p.toFile().getName().matches(nameRegEx))
            .findFirst();

Comments

0

You cannot use a regex directly to an FileInputStream, However, you can read all the files and then filter out the required once like below. If reading all can be done in your case,

File folder = new File( "/user/folder/" ); // Base folder where you have all the files
List<File> collectedFiles = Arrays.stream( folder.listFiles() )
                                  .filter( file -> file.getName().contains( "1525" ) ) // Check if filename as your employee number
                                  .collect( Collectors.toList() ); // Get all the filtered files as a list

Another approach is to use the FileNameFilter

FilenameFilter filter = ( dir, name ) -> name.contains( "1525" );
File folder = new File( "/user/folder/" ); // Base folder where you have all the files
List<File> collectedFiles = Arrays.stream( folder.listFiles(filter) )
                                  .collect( Collectors.toList() );

2 Comments

will this way slow down the loading of the images on my app though if there is a large amount of images to go through? Eventually there will be a few hundred images
@dmcd eventually, it has to filter out the names by looking at all the names available. One approach is use can use the FileNameFilter directly. See my updated answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.