-1

I need some help in picking the exact file from directory on Windows using Java. Below is the code which I have written for this. But when I pass my input as "XYZ" file it always picks the "ABC" file only.

My input to pick the file was 'XYZ', but output always returns 'ABC' file

directoryPath = new File(System.getProperty("user.dir") + "\\TestFilesDirectory\\");
String contents[] = directoryPath.list();
            System.out.println("List of files and directories in the specified directory : " + directoryPath);
            for (int i = 0; i < contents.length; i++) {
                // System.out.println(contents[i]);
                ArrayList<String> fileNameList = new ArrayList<String>();
                String[] fileNameSplit = contents[i].split("_");

                for (int k = 0; k < fileNameSplit.length; k++) {
                    // System.out.println(fileNameSplit[k].toUpperCase());
                    fileNameList.add(fileNameSplit[k].toUpperCase());

                }

                if (fileNameList.contains("ABC") {
                    System.out.println("Pick ABC file from directory ");
                    source = new File(directoryPath + "\\" + contents[i] + "");
                    }

                    System.out.println("Base File: " + source);
                else  if (fileNameList.contains("DEF") {
                System.out.println("Pick DEF file from directory ");
                    source = new File(directoryPath + "\\" + contents[i] + "");
                }
                else if (fileNameList.contains("XYZ") {
                System.out.println("Pick XYZ file from directory ");
                    source = new File(directoryPath + "\\" + contents[i] + "");
                }

Below are my files in Test directory:

Test Directory files

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
Quick learner
  • 699
  • 4
  • 22
  • 39
  • 1
    I think you want your `else` statements to be `else if`. – Tim Moore Sep 21 '21 at 04:01
  • my bad! its copy paste mistake. I have kept else if only, but still picking the ABC file instead XYZ. – Quick learner Sep 21 '21 at 04:04
  • How and where do you get your input? Your code does not show anything that uses an input. – sorifiend Sep 21 '21 at 04:05
  • @sorifiend My input was having multiple parameters as per my requirements, but the code which i posted here was, i'll pass the file name as written in description. and based on file input particular should pick from my test directory. Hope you got my point. – Quick learner Sep 21 '21 at 04:11
  • 1
    Then I don't see the problem. The code in your question is a simple loop to find and print out any files in a folder with a title that contains ABC, DEF or XYZ. Note that all your if/else checks interact with the `source` variable. If you want to allow for multiple files then use an to store your `source` files in an array instead of a single variable. What is the actual issue or problem that you have? Do you need to know how to input a value to choose if you should use ABC, DEF or XYZ? Then see here: https://stackoverflow.com/questions/5287538/how-to-get-the-user-input-in-java – sorifiend Sep 21 '21 at 04:16
  • in your if statement use a `=` for `i < contents.length`, change it to `i <= contents.length` – Issa Khodadadi Sep 21 '21 at 04:24
  • @mr1554 That will cause an `IndexOutOfBoundsException`, remember that an array starts from 0, not from 1. – sorifiend Sep 21 '21 at 04:29
  • In the future [please do not upload images of code/errors when asking a question.](//meta.stackoverflow.com/q/285551) – Joachim Sauer Sep 21 '21 at 09:11

1 Answers1

1

I think that your code can be improved. As far as I can tell you need to retrieve the path of a given file matching either the first or second part of its filename. So for example:

DEF_GHI.txt

can be matched by either inputting def or ghi into your search method. The easiest and most concise way to do so would be:

public Optional<File> findByName(String name, String directoryPath) {
    try (var fileStream = Files.list(Path.of(directoryPath))) {
        return fileStream
        .filter(path -> Arrays.stream(path.getFileName().toString().split("_"))
            .map(part -> part.replaceAll("\\.[^.]*$", ""))
            .anyMatch(part -> part.equalsIgnoreCase(name)))
        .findAny()
        .map(Path::toFile);
    } catch (IOException e) {
        System.err.println("Unable to open directory stream for path:: " + directoryPath);
        e.printStackTrace();
    }
    return Optional.empty();
}

What this does is the following:

  1. Accepts a filename and a path representing a directory to search at
  2. Creates a stream of paths representing the files under the given directory
  3. Gets the filename for each given path and performs the following:
    1. Splits the string using _ in order to retrieve both parts (if present)
    2. Replaces everything after the . character (including it) in order to get rid of the file extension.
    3. Attempts to match each part against the provided name parameter
    4. Map the found path value to a File (if present)
  4. Lastly returns either the optionally wrapped File or an empty Optional.

I hope this is what you are looking for.

akortex
  • 5,067
  • 2
  • 25
  • 57