0

I have to following code that does return 0 for every file. I am wondering what is the correct way of get the file size with Files/Path.

import java.nio.file.Files;
import java.nio.file.Path;

Stream<Path> files = Files.list(new File("/tmp").toPath());

 files.filter(p -> p.getFileName().toString().endsWith(".test"))
      .filter(p -> p.getFileName().toFile().length() > 0)
      .filter(p -> Files.isRegularFile(p))
      .forEach(filePath -> {
        Log.info("Size of file KB :: " +
                String.valueOf(
                  filePath.getFileName().toFile().length() / 1024));
        });
Istvan
  • 7,500
  • 9
  • 59
  • 109
  • 1
    Why not `filePath.toFile()` instead of `filePath.getFileName().toFile()`? – Thomas Mar 21 '17 at 12:08
  • 1
    Note that due to integer math 1023/1024 will be 0, i.e. any file whose size is 0.xxx KB will be reported as 0. Instead use floating point math, e.g. `... / 1024.0`. – Thomas Mar 21 '17 at 12:11
  • @Thomas your suggestion fixed the issue. – Istvan Mar 21 '17 at 12:28

1 Answers1

0

As suggested by @Thomas using directly p.toFile().length() works correctly:

   try (Stream<Path> files = Files.list(new File("/tmp").toPath())) {
        files.filter(p -> p.getFileName().toString().endsWith(".crc"))
                .filter(p -> p.toFile().length() > 0)
                .filter(p -> Files.isRegularFile(p))
                .forEach(filePath -> {
                    Log.info("Size of file B :: " + String.valueOf(filePath.toFile().length()));
                });
    } catch (IOException ex) {
        Log.error("IOE");
    }

Results are showing the correct size in bytes:

2017-03-21 13:27:17 INFO  GenerateTestData:353 - Size of file B :: 824
2017-03-21 13:27:17 INFO  GenerateTestData:353 - Size of file B :: 952
2017-03-21 13:27:17 INFO  GenerateTestData:353 - Size of file B :: 964
2017-03-21 13:27:17 INFO  GenerateTestData:353 - Size of file B :: 824
2017-03-21 13:27:17 INFO  GenerateTestData:353 - Size of file B :: 684
Istvan
  • 7,500
  • 9
  • 59
  • 109
  • Note that `filePath.getFileName().toFile()` probably would work as well. The sizes you get are all below 1024 and thus `824/1024` will result in 0 due to integer math (see [here](http://stackoverflow.com/questions/7220681/division-of-integers-in-java) for example). If you'd change that to floating point math, e.g. by casting one operand to `double` or using a literal like `1024.0` it should work as well. – Thomas Mar 21 '17 at 15:24