1

As per this 3rd answer , I can write a file like this

Files.write(Paths.get("file6.txt"), lines, utf8,
        StandardOpenOption.CREATE, StandardOpenOption.APPEND);

however when I try it on my code I got this error :

The method write(Path, Iterable, Charset, OpenOption...) in the type Files is not applicable for the arguments (Path, byte[], Charset, StandardOpenOption)

this is my code :

    File dir = new File(myDirectoryPath);
    File[] directoryListing = dir.listFiles();
    if (directoryListing != null) {
        File newScript = new File(newPath + "//newScript.pbd");     
            if (!newScript.exists()) {
                newScript.createNewFile();
            }
        for (File child : directoryListing) {

            if (!child.isDirectory()) {
                byte[] content = null;
                Charset utf8 = StandardCharsets.UTF_8;

                content = readFileContent(child);
                try {

                    Files.write(Paths.get(newPath + "\\newScript.pbd"), content,utf8,
                            StandardOpenOption.APPEND); <== error here in this line.

                } catch (Exception e) {
                    System.out.println("COULD NOT LOG!! " + e);
                }
            }

        }
    }

Note if change my code to like it work and it writes into the file (remove utf8).

                    Files.write(Paths.get(newPath + "\\newScript.pbd"), content,
                            StandardOpenOption.APPEND);
Zabuzard
  • 25,064
  • 8
  • 58
  • 82
Moudiz
  • 7,211
  • 22
  • 78
  • 156
  • an array like `byte[]` is not `Iterable`. – Zabuzard Nov 27 '19 at 07:45
  • @Zabuza so why its considering it as Iterable.? – Moudiz Nov 27 '19 at 07:46
  • 1
    You most likely intended to call this method https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/nio/file/Files.html#write(java.nio.file.Path,byte%5B%5D,java.nio.file.OpenOption...) i.e. without charset. – Zabuzard Nov 27 '19 at 07:46
  • @Zabuza so the answer in that question is wrong as I cannot use charset and byte as same argument. Correct ? – Moudiz Nov 27 '19 at 07:48
  • 2
    It is not considered as Iterable but the closest method matching your call is the version with the Iterable. But an array of bytes does not apply for that. You want the variant that takes `byte[]` but that variant does not take a charset. Because a charset makes no sense if the data is already binary. Since the sole purpose of a charset is to convert correctly from `String` to binary `byte[]`. You did that already before. – Zabuzard Nov 27 '19 at 07:48
  • 2
    Yes, because a charset makes no sense in that context. The charset would need to be specified where you go from String to binary, i.e. at your reading stage. Note that all methods in `Files` use UTF-8 by default already, so no need to specify it anyways. – Zabuzard Nov 27 '19 at 07:49
  • 1
    @Zabuza ok thanks, you were helpful, please provide it as answer to accept. – Moudiz Nov 27 '19 at 07:51

2 Answers2

3

Explanation

There are 3 overloads of the Files#write method (see the documentation):

  • Takes Path, byte[], OpenOption... (no charset)
  • Takes Path, Iterable<? extends CharSequence>, OpenOption... (like List<String>, no charset, uses UTF-8)
  • Takes Path, Iterable<? extends CharSequence>, Charset, OpenOption... (has charset)

For your call (Path, byte[], Charset, OpenOption...), no matching version exists. Thus, it does not compile.

It does not match the first and second overload, since they do not support the Charset and it does not match the third overload, since neither is an array Iterable (a class like ArrayList is), nor does byte extend CharSequence (String does).

In the error message you can see what Java computed as closest match to your call, unfortunately (as explained), it is not applicable for your arguments.


Solution

You most likely intended to go for the first overload:

Files.write(Paths.get("file6.txt"), lines,
    StandardOpenOption.CREATE, StandardOpenOption.APPEND);

I.e. no charset.


Notes

A charset makes no sense in your context. The sole purpose of a charset is to convert correctly from String to binary byte[]. But your data is already binary, so the charset comes in place before that. In your case that would be the reading phase in readFileContent.

Also note that all methods in Files use UTF-8 by default already. So no need to additionally specify it anyways.

When specifying OpenOptions, you may also want to specify whether it is StandardOpenOption.READ or StandardOpenOption.WRITE mode. The Files#write method by default uses:

WRITE
CREATE
TRUNCATE_EXISTING

So you may want to call it with

WRITE
CREATE
APPEND

Examples

Here are some snippets of how to fully read and write in text and binary, in UTF-8:

// Text mode
List<String> lines = Files.readAllLines(inputPath);
// do something with lines
Files.write(outputPath, lines);

// Binary mode
byte[] content = Files.readAllBytes(inputPath);
// do something with content
Files.write(outputPath, content);
Zabuzard
  • 25,064
  • 8
  • 58
  • 82
-1

in the 3rd answer you have mentioned the content of the file is iterable, namely List. You can not use this method with a byte[]. Make your readFileContent() method return something iterable like List (each element is a line of your file).

Volokh
  • 380
  • 3
  • 16