简体   繁体   English

使用Java 7 nio读写文件

[英]Reading and writing files using Java 7 nio

I have files which consist of json elements in an array. 我有包含数组中的json元素的文件。 (several file. each file has json array of elements) (几个文件。每个文件都有json元素数组)

I have a process that knows to take each json element as a line from file and process it. 我有一个知道将每个json元素作为文件中的一行进行处理的过程。

So I created a small program that reads the JSON array, and then writes the elements to another file. 因此,我创建了一个读取JSON数组的小程序,然后将元素写入另一个文件。 The output of this utility will be the input of the other process. 该实用程序的输出将是其他进程的输入。

I used Java 7 NIO (and gson). 我使用了Java 7 NIO(和gson)。

I tried to use as much Java 7 NIO as possible. 我尝试使用尽可能多的Java 7 NIO。 Is there any improvement I can do? 我有什么可以改善的吗? What about the filter? 过滤器呢? Which approach is better? 哪种方法更好?

Thanks, 谢谢,

public class TransformJsonsUsers {

public TransformJsonsUsers() {
}

public static void main(String[] args) throws IOException {
    final Gson gson = new Gson();

    Path path = Paths.get("C:\\work\\data\\resources\\files");
    final Path outputDirectory = Paths
            .get("C:\\work\\data\\resources\\files\\output");

    DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {

        @Override
        public boolean accept(Path entry) throws IOException {
            // which is better?
            // BasicFileAttributeView attView = Files.getFileAttributeView(entry, BasicFileAttributeView.class);
           // return attView.readAttributes().isRegularFile();
            return !Files.isDirectory(entry);
        }

    };

    DirectoryStream<Path> directoryStream = Files.newDirectoryStream(path, filter);

    directoryStream.forEach(new Consumer<Path>() {
        @Override
        public void accept(Path filePath) {
            String fileOutput = outputDirectory.toString() + File.separator + filePath.getFileName();
            Path fileOutputPath = Paths.get(fileOutput);
            try {
                BufferedReader br = Files.newBufferedReader(filePath);
                User[] users = gson.fromJson(br, User[].class);
                BufferedWriter writer = Files.newBufferedWriter(fileOutputPath, Charset.defaultCharset());
                for (User user : users) {
                    writer.append(gson.toJson(user));
                    writer.newLine();
                }
                writer.flush();
            } catch (IOException e) {
                throw new RuntimeException(filePath.toString(), e);
            }

        }
    });
}

} }

There is no point of using Filter if you want to read all the files from the directory. 如果要从目录中读取所有文件,则没有必要使用过滤器。 Filter is primarily designed to apply some filter criteria and read a subset of files. 筛选器主要用于应用某些筛选条件并读取文件的子集。 Both of them may not have any real difference in over all performance. 两者在整体性能上可能没有任何实际差异。

If you looking to improve performance, you can try couple different approaches. 如果您想提高性能,可以尝试几种不同的方法。

Multi-threading 多线程

Depending on how many files exists in the directory and how powerful your CPU is, you can apply multi threading to process more than one file at a time 根据目录中存在多少文件以及您的CPU的强大程度,您可以应用多线程来一次处理多个文件

Queuing 排队

Right now you are reading and writing to another file synchronously. 现在,您正在同步读取和写入另一个文件。 You can queue content of the file using Queue and create asynchronous writer. 您可以使用Queue排队文件的内容并创建异步编写器。

You can combine both of these approaches as well to improve performance further. 您也可以将这两种方法结合起来以进一步提高性能。

Don't put the I/O into the filter. 不要将I / O放入过滤器。 That's not what it's for. 那不是它的目的。 You should get the complete list of files and then process it. 您应该获取文件的完整列表, 然后进行处理。 For example if the I/O creates another file in the directory, the behaviour is undefined. 例如,如果I / O在目录中创建另一个文件,则该行为是未定义的。 You might miss a file, or see the new file in the accept() method. 您可能会错过一个文件,或者在accept()方法中看到新文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM