Home > database >  Java parses File.separator as \ which isn't recognized as legit file path
Java parses File.separator as \ which isn't recognized as legit file path

Time:01-07

I'm not really sure when it started, but my Selenium framework stopped accepting path names with File.separator, I must use backslashes or I can't upload files.

If I type path like this:

String DOCX = "uploads"   File.separator   "mock"   File.separator   "document_donotparse.docx";

I get such an error:

invalid argument: File not found : C:\XXX\Arbeit\tests\build\resources\test\uploads\mock\document_donotparse.docx

So basically File.separator gets translated to \

Now this is the code I am using:

    public void uploadFiles(@NotNull List<String> filenames, By input, By progressBar, FileType fileType) {
        log.trace("Uploading files: {}", filenames);
        getExistingElement(input).sendKeys(Utils.parseFilenamesForMultipleUpload(filenames));
        throwIfParsingFailed(fileType);
        waitForAllElementsToDisappear(progressBar);
    }

and since I also need to upload multiple files at once, I need the util function:

    public String parseFilenamesForMultipleUpload(@NotNull Collection<String> filenames) {
        return String.join(" \n ", filenames
                .stream()
                .map(filename -> new File(Objects.requireNonNull(
                        Utils.class.getClassLoader().getResource(filename)).getFile()).getAbsolutePath())
                .toList());
    }

The only thing that worked so far was basically changing code to use "normal" backslashes:

String DOCX = "uploads/mock/document_donotparse.docx";

I would, however, like to use File.separator back again.

Also I am having no problems at all when reading json or properties files, for which paths are also separated with File.separator, so the problem must lie somewhere with the upload code.

CodePudding user response:

Thanks to @hiren I pinpointed that the place where parsing to \ occured was parseFilenamesForMultipleUpload. So I added URLDecoder to get rid of percentages and created my own method removePath to remove path part of file regardless of type of file separator.

Here is the the code:

parseFilenamesForMultipleUpload is very similiar I just added more mappings to make it cleaner and added mapping through decodeQuery method, which simply translates percentages.

    public String parseFilenamesForMultipleUpload(@NotNull Collection<String> filenames) {
        return filenames
                .stream()
                .map(Utils::getFile)
                .map(File::getPath)
                .map(Utils::decodeQuery)
                .collect(Collectors.joining("\n"));
    }

Utils#getFile is simply some code from previous version of parseFilenamesForMultipleUpload method extracted fo clarity:

    @Contract("_ -> new")
    private @NotNull File getFile(String filename) {
        return new File(Objects.requireNonNull(Utils.class.getClassLoader().getResource(filename)).getFile());
    }

I then map it again with File#getPath instead of File#AbsolutePath like before, and finally decodeQuery translates percentage style.

Utils#decodeQuery:

    public String decodeQuery(String query) {
        return URLDecoder.decode(query, StandardCharsets.UTF_8);
    }

And finally I join them with a newline character.

Then, to be able to extract filename from filepath I created such method:

    public String removePath(@NotNull String filepath) {
        for (char c : new char[]{'/', '\\', File.separatorChar, File.pathSeparatorChar}) {
            filepath = cutFilePath(filepath, c);
        }
        return filepath;
    }

where cutFilePath is:

    private @NotNull String cutFilePath(@NotNull String filepath, char delimiter) {
        int charIndex = filepath.lastIndexOf(delimiter);
        return charIndex > -1 ? filepath.substring(charIndex   1) : filepath;
    }

Everything is working :)

  • Related