4
\$\begingroup\$

What I'm wanting to do is create a String readFile(Path filePath, Charset encoding) method, that returns the entire contents of a given file.

I'm wanting the equivalent of Guava's Files.toString(file, encoding), but without calling the Path.getFile() method (as this method only works with the default filesystem provider, and in this particular case I'm wanting to write tests that use JimFS).

I've written the following, but I'm wondering if it can be improved:

import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import java.nio.file.Files;
⋮
public String readFile(Path path, Charset encoding) throws IOException {
 Preconditions.checkState(Files.exists(path), "File does not exist: %s", path);
 Preconditions.checkState(Files.isRegularFile(path), "File is not regular file: %s", path);
 return Joiner.on(System.lineSeparator()).join(Files.readAllLines(path, encoding));
} 

Is there a better way to read the file in (such as without using Files.readAllLines() which results in a slightly awkward List<String>). I'd previously joined this result together by streaming the lines of the file, and then immediately collecting them with Collectors.joining(System.lineSeparator()), but since the project has a dependency on Guava for other purposes, it seems preferable to use the Joiner available.

I'm happy to restrict this to Java 8 and onwards if needed, and as previously mentioned I already have a dependency on Guava, but I'd rather not add too many dependencies if possible.

asked Jan 23, 2016 at 23:17
\$\endgroup\$
1

1 Answer 1

5
\$\begingroup\$

I believe you are missing a relatively obvious, although somewhat memory-inefficient Files.readAllBytes(...) .... Consider this:

public String readFile(Path path, Charset encoding) throws IOException {
 return new String(Files.readAllBytes(path), encoding);
}

In your code you also have two full copies of the file in-memory at one time, so the files can't be huge. The code I suggest also pulls all the data in to memory twice, once as a byte[] array, which gets converted to a String, and the byte[] array is discarded.

There would be a loopy way to solve it by using a StringBuilder and a smaller byte[] array, or ByteBuffer, but, if your files are smallish, I would not worry about the byte[] size.

answered Jan 23, 2016 at 23:42
\$\endgroup\$
1
  • \$\begingroup\$ Yup, that was obvious! And yes, the files are smallish anyway, so I'm not too concerned about storing everything in-memory inefficiently in this case. \$\endgroup\$ Commented Jan 24, 2016 at 11:26

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.