Java 读取文件和解析每一行的有效方法

Java 读取文件和解析每一行的有效方法,java,nio,java-io,Java,Nio,Java Io,我有一个下一种格式的文本文件:每行以一个字符串开头,后面是数字序列。每行长度未知(数字数量未知,数量从0到1000) 之后,我必须使用handleLine方法处理每一行,该方法接受两个参数:字符串名称和数字集(见下面的代码) 如何有效地读取文件并使用handleLine处理每一行 我的解决方法: 使用java8 streamsFiles.lines逐行读取文件。它阻塞了吗 用regexp拆分每一行 将每行转换为标题字符串和数字集 我认为第二步和第三步是相当无效的。第一步意味着java首先将文件字

我有一个下一种格式的文本文件:每行以一个字符串开头,后面是数字序列。每行长度未知(数字数量未知,数量从0到1000)

之后,我必须使用
handleLine
方法处理每一行,该方法接受两个参数:字符串名称和数字集(见下面的代码)

如何有效地读取文件并使用
handleLine
处理每一行

我的解决方法:

  • 使用java8 streams
    Files.lines
    逐行读取文件。它阻塞了吗
  • 用regexp拆分每一行
  • 将每行转换为标题字符串和数字集
  • 我认为第二步和第三步是相当无效的。第一步意味着java首先将文件字节转换为字符串,然后在第二步和第三步中,我将它们转换回
    字符串
    /
    。这对性能有很大影响吗?如果是-如何做得更好

    公共句柄文件(字符串文件路径){
    try(Stream=Files.line(path.get(filePath))){
    forEach(this::indexLine);
    }捕获(IOE异常){
    e、 printStackTrace();
    }
    }
    专用空白扶手线(字符串线){
    List resultList=this.parse(行);
    String_i=resultList.remove(0);
    Set numbers=resultList.stream().map(Integer::valueOf).collect(Collectors.toSet());
    handleLine(string_i,numbers);//这里是最后的计算,必须只使用string_i&numbers参数来完成
    }
    私有列表解析(字符串str){
    列表输出=新建LinkedList();
    Matcher match=Pattern.compile(“[0-9]+|[a-z]+|[a-z]+”)。Matcher(str);
    while(match.find()){
    add(match.group());
    }
    返回输出;
    }
    
    关于您的第一个问题,这取决于您如何引用
    流<代码>流
    天生就是懒惰的,如果不打算使用它,就不会工作。例如,在
    上添加终端操作之前,对
    Files.lines的调用实际上不会读取文件

    从java文档:

    将文件中的所有行作为流读取。与readAllLines不同,此方法不会将所有行读取到列表中,而是在使用流时缓慢填充

    forEach(Consumer)
    调用是一个终端操作,此时,文件的行将被逐个读取并传递给
    indexLine
    方法


    关于你的其他评论,你在这里真的没有问题。你想测量什么?仅仅因为某些东西是多步骤的,并不意味着它的性能就差。即使您创建了一个wizbang oneliner,将
    文件
    字节直接转换为
    字符串
    &
    ,您可能只是匿名进行了中间映射,或者调用了某种东西,这将导致编译器执行此操作。

    关于您的第一个问题,这取决于引用
    流的方式<代码>流
    天生就是懒惰的,如果不打算使用它,就不会工作。例如,在
    上添加终端操作之前,对
    Files.lines的调用实际上不会读取文件

    从java文档:

    将文件中的所有行作为流读取。与readAllLines不同,此方法不会将所有行读取到列表中,而是在使用流时缓慢填充

    forEach(Consumer)
    调用是一个终端操作,此时,文件的行将被逐个读取并传递给
    indexLine
    方法


    关于你的其他评论,你在这里真的没有问题。你想测量什么?仅仅因为某些东西是多步骤的,并不意味着它的性能就差。即使您创建了一个wizbang oneliner,将
    文件
    字节直接转换为
    字符串
    &
    ,也可能只是匿名进行了中间映射,或者您调用了一些东西,这将导致编译器执行此操作。

    以下是将行解析为名称和数字的代码

    stream.forEach(line -> {
        String[] split = line.split("\\b"); //split with blank seperator
        Set<String> numbers = IntStream.range(1, split.length)
                                    .mapToObj(index -> split[index])
                                    .filter(str -> str.matches("\\d+")) //filter numbers
                                    .collect(Collectors.toSet());
        handleLine(split[0], numbers);
    });
    
    stream.forEach(行->{
    String[]split=line.split(\\b”);//使用空白分隔符分割
    Set number=IntStream.range(1,split.length)
    .mapToObj(索引->拆分[索引])
    .filter(str->str.matches(“\\d+”)//过滤器编号
    .collect(收集器.toSet());
    扶手线(拆分[0],编号);
    });
    
    或者以另一种方式

    Map<Boolean, List<String>> collect = Pattern.compile("\\b")
                                                .splitAsStream(line)
                                                .filter(str -> !str.matches("\\b"))
                                                .collect(Collectors.groupingBy(str -> str.matches("\\d+")));
    handleLine(collect.get(Boolean.FALSE).get(0), collect.get(Boolean.TRUE));
    
    Map collect=Pattern.compile(\\b)
    .splitAsStream(行)
    .filter(str->!str.matches(\\b”))
    .collect(Collectors.groupingBy(str->str.matches(\\d+)));
    handleLine(collect.get(Boolean.FALSE).get(0),collect.get(Boolean.TRUE));
    
    这是将行解析为名称和数字的代码

    stream.forEach(line -> {
        String[] split = line.split("\\b"); //split with blank seperator
        Set<String> numbers = IntStream.range(1, split.length)
                                    .mapToObj(index -> split[index])
                                    .filter(str -> str.matches("\\d+")) //filter numbers
                                    .collect(Collectors.toSet());
        handleLine(split[0], numbers);
    });
    
    stream.forEach(行->{
    String[]split=line.split(\\b”);//使用空白分隔符分割
    Set number=IntStream.range(1,split.length)
    .mapToObj(索引->拆分[索引])
    .filter(str->str.matches(“\\d+”)//过滤器编号
    .collect(收集器.toSet());
    扶手线(拆分[0],编号);
    });
    
    或者以另一种方式

    Map<Boolean, List<String>> collect = Pattern.compile("\\b")
                                                .splitAsStream(line)
                                                .filter(str -> !str.matches("\\b"))
                                                .collect(Collectors.groupingBy(str -> str.matches("\\d+")));
    handleLine(collect.get(Boolean.FALSE).get(0), collect.get(Boolean.TRUE));
    
    Map collect=Pattern.compile(\\b)
    .splitAsStream(行)
    .filter(str->!str.matches(\\b”))
    .collect(Collectors.groupingBy(str->str.matches(\\d+)));
    handleLine(collect.get(Boolean.FALSE).get(0),collect.get(Boolean.TRUE));
    
    我开始测试解决这个问题的几种方法,并将性能作为最佳的IC来衡量
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.util.ArrayList;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Random;
    import java.util.Scanner;
    import java.util.Set;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
    import java.util.stream.Stream;
    
    public class App {
    
        public static void method1(String testFile) {
            List<Integer> nums = null;
            try (Scanner s = new Scanner(Paths.get(testFile))) {
                while (s.hasNext()) {
                    if (s.hasNextInt())
                        nums.add(s.nextInt());
                    else {
                        nums = new ArrayList<Integer>();
                        String pre = s.next();
                        // handleLine( s.next() ... nums ... );
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void method2(String testFile) {
            List<Integer> nums = null;
            try (BufferedReader in = new BufferedReader(new FileReader(testFile));
                    Scanner s = new Scanner(in)) {
                while (s.hasNext()) {
                    if (s.hasNextInt())
                        nums.add(s.nextInt());
                    else {
                        nums = new ArrayList<Integer>();
                        String pre = s.next();
                        // handleLine( s.next() ... nums ... );
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void method3(String testFile) {
            List<Integer> nums = null;
            try (BufferedReader br = new BufferedReader(new FileReader(testFile))) {
                String line = null;
                while ((line = br.readLine()) != null) {
                    String[] arr = line.split(" ");
                    nums = new ArrayList<Integer>();
                    for (int i = 1; i < arr.length; ++i)
                        nums.add(Integer.valueOf(arr[i]));
                    // handleLine( ... );
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void method3_1(String testFile) {
            List<Integer> nums = null;
            try (BufferedReader br = new BufferedReader(new FileReader(testFile))) {
                String line = null;
                while ((line = br.readLine()) != null) {
                    String[] arr = line.split(" ");
                    nums = new ArrayList<Integer>();
                    for (int i = 1; i < arr.length; ++i)
                        nums.add(Integer.parseInt(arr[i]));
                    // handleLine( ... );
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void method4(String testFile) {
            List<Integer> nums = null;
            try {
                List<String> lines = Files.readAllLines(Paths.get(testFile));
                for (String s : lines) {
                    String[] arr = s.split(" ");
                    nums = new ArrayList<Integer>();
                    for (int i = 1; i < arr.length; ++i)
                        nums.add(Integer.valueOf(arr[i]));
                    // handleLine( ... );
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void method4_1(String testFile) {
            List<Integer> nums = null;
            try {
                List<String> lines = Files.readAllLines(Paths.get(testFile));
                for (String s : lines) {
                    String[] arr = s.split(" ");
                    nums = new ArrayList<Integer>();
                    for (int i = 1; i < arr.length; ++i)
                        nums.add(Integer.parseInt(arr[i]));
                    // handleLine( ... );
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void method5(String testFile) {
            List<Integer> nums = null;
            try (BufferedReader br = Files.newBufferedReader(Paths.get(testFile))) {
                List<String> lines = br.lines().collect(Collectors.toList());
                for (String s : lines) {
                    String[] arr = s.split(" ");
                    nums = new ArrayList<Integer>();
                    for (int i = 1; i < arr.length; ++i)
                        nums.add(Integer.valueOf(arr[i]));
                    // handleLine( ... );
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void method5_1(String testFile) {
            List<Integer> nums = null;
            try (BufferedReader br = Files.newBufferedReader(Paths.get(testFile))) {
                List<String> lines = br.lines().collect(Collectors.toList());
                for (String s : lines) {
                    String[] arr = s.split(" ");
                    nums = new ArrayList<Integer>();
                    for (int i = 1; i < arr.length; ++i)
                        nums.add(Integer.parseInt(arr[i]));
                    // handleLine( ... );
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void method6(String testFile) {
            List<Integer> nums = new LinkedList<Integer>();
            try (Stream<String> stream = Files.lines(Paths.get(testFile))) {
                stream.forEach(line -> {
                    String[] split = line.split("\\b"); // split with blank seperator
                    Set<String> numbers = IntStream.range(1, split.length)
                            .mapToObj(index -> split[index])
                            .filter(str -> str.matches("\\d+")) // filter numbers
                            .collect(Collectors.toSet());
                    numbers.forEach((k) -> nums.add(Integer.parseInt(k)));
                    // handleLine( ... );
                });
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) throws Exception {
    
            args = new String[] { "C:\\Users\\Nick\\Desktop\\test.txt" };
    
            Random r = new Random();
    
            System.out.println("warming up a little...");
            for (int i = 0; i < 100000; ++i) {
                int x = r.nextInt();
            }
    
            long s1 = System.currentTimeMillis();
            for (int i = 0; i < 10000; ++i)
                method1(args[0]);
            long e1 = System.currentTimeMillis();
    
            long s2 = System.currentTimeMillis();
            for (int i = 0; i < 10000; ++i)
                method2(args[0]);
            long e2 = System.currentTimeMillis();
    
            long s3 = System.currentTimeMillis();
            for (int i = 0; i < 10000; ++i)
                method3(args[0]);
            long e3 = System.currentTimeMillis();
    
            long s3_1 = System.currentTimeMillis();
            for (int i = 0; i < 10000; ++i)
                method3_1(args[0]);
            long e3_1 = System.currentTimeMillis();
    
            long s4 = System.currentTimeMillis();
            for (int i = 0; i < 10000; ++i)
                method4(args[0]);
            long e4 = System.currentTimeMillis();
    
            long s4_1 = System.currentTimeMillis();
            for (int i = 0; i < 10000; ++i)
                method4_1(args[0]);
            long e4_1 = System.currentTimeMillis();
    
            long s5 = System.currentTimeMillis();
            for (int i = 0; i < 10000; ++i)
                method5(args[0]);
            long e5 = System.currentTimeMillis();
    
            long s5_1 = System.currentTimeMillis();
            for (int i = 0; i < 10000; ++i)
                method5_1(args[0]);
            long e5_1 = System.currentTimeMillis();
    
            long s6 = System.currentTimeMillis();
            for (int i = 0; i < 10000; ++i)
                method6(args[0]);
            long e6 = System.currentTimeMillis();
    
            System.out.println("method 1 = " + (e1 - s1) + " ms");
            System.out.println("method 2 = " + (e2 - s2) + " ms");
            System.out.println("method 3 = " + (e3 - s3) + " ms");
            System.out.println("method 3_1 = " + (e3_1 - s3_1) + " ms");
            System.out.println("method 4 = " + (e4 - s4) + " ms");
            System.out.println("method 4_1 = " + (e4_1 - s4_1) + " ms");
            System.out.println("method 5 = " + (e5 - s5) + " ms");
            System.out.println("method 5_1 = " + (e5_1 - s5_1) + " ms");
            System.out.println("method 6 = " + (e6 - s6) + " ms");
        }
    }
    
    warming up a little...
    method 1 = 1103 ms
    method 2 = 872 ms
    method 3 = 440 ms
    method 3_1 = 418 ms
    method 4 = 413 ms
    method 4_1 = 376 ms
    method 5 = 439 ms
    method 5_1 = 384 ms
    method 6 = 646 ms
    
    my_name 15 00 29 101 1234
    cool_id 11 00 01 10 010101
    longer_id_name 1234
    dynamic_er 1 2 3 4 5 6 7 8 9 10 11 12 123 1456 15689 555555555