Java读取文件方式

本文介绍了Java中多种读取文件的方法,包括使用BufferedReader按行读取,指定和不指定编码格式,使用Scanner和NIOAPI进行读取,以及利用Hutool和ApacheCommons-IO工具库简化操作。同时强调了处理编码问题和大文件读取的策略。
摘要由CSDN通过智能技术生成

IO流读取

文本内容

 

按行读取文件内容

指定编码格式(推荐)

 public static void main(String[] args) throws UnsupportedEncodingException {
        read("D:\\test.txt");

    }

    public static void read(String path) {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(
                    new InputStreamReader(new FileInputStream(path), "UTF-8"));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

 注意,如果控制台输出为乱码,需要度idea进行配置,依次选择file-Setting-editor-File Encoding

 不指定编码格式

 public static void main(String[] args) throws IOException {
        read("D:\\test.txt");

    }

    public static void read(String path) throws IOException {
        BufferedReader reader = new BufferedReader(new FileReader(path));
        String line;
        while ((line = reader.readLine()) != null)
        {
            System.out.println(line);
        }
        reader.close();
    }

可能出现乱码。

按字符读取文件内容

 public static void read(String path) throws IOException {
        Reader reader = new InputStreamReader(new FileInputStream(path));
        int tempchar;
        while ((tempchar = reader.read()) != -1) {
            System.out.print((char) tempchar);
        }
        reader.close();
    }

按字节读取文件内容

常用于读取图片,声音,影像等

单字节读取

 public static void read(String path) throws IOException {
        FileInputStream reader = new FileInputStream(path);
        int tempchar;
        while ((tempchar = reader.read()) != -1) {
            System.out.print((char) tempchar);
        }
        reader.close();
    }

多字节读取

 public static void read(String path) throws IOException {
        FileInputStream reader = new FileInputStream(path);
        byte[] tempByte = new byte[1024];
        int len = 0 ;
        while((len = reader.read(tempByte))!= -1){
            for (int i = 0; i <len; i++) {
                System.out.print((char)tempByte[i]);
            }
        }
        reader.close();
    }

Scanner

第一种方式是Scanner,从JDK1.5开始提供的API,特点是可以按行读取、按分割符去读取文件数据,既可以读取String类型,也可以读取Int类型、Long类型等基础数据类型的数据。

  public static void read(String path) throws IOException {
        try (Scanner sc = new Scanner(new FileReader(path))) {
            while (sc.hasNextLine()) {  //按行读取字符串
                String line = sc.nextLine();
                System.out.println(line);
            }
        }
    }

JDK1.7提供的NIO读取文件

小文件

 public static void read(String path) throws IOException {
        final String CHARSET_NAME = "UTF-8";

        List<String> content = new ArrayList<>(0);

        try {
            content = Files.readAllLines(Paths.get(path), Charset.forName(CHARSET_NAME));
        } catch (Exception e) {
            e.printStackTrace();
        }

       content.forEach(System.out::println);

    }

大文件

 public static void read(String path) throws IOException {
        final String CHARSET_NAME = "UTF-8";

        List<String> content = new ArrayList<>(0);


        try (BufferedReader br = Files.newBufferedReader(Paths.get(path), Charset.forName(CHARSET_NAME))) {
            String line;
            while ((line = br.readLine()) != null) {
                content.add(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

       content.forEach(System.out::println);

    }

JDK1.4提供的NIO读取文件(适用于超大文件)

public static void read(String path) throws IOException {
        final String CHARSET_NAME = "UTF-8";

        final int ASCII_LF = 10; // 换行符
        final int ASCII_CR = 13; // 回车符

        List<String> content = new ArrayList<>();

        try (FileChannel fileChannel = new RandomAccessFile(path, "r").getChannel()) {
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 100);
            byte[] lineByte;

            byte[] temp = new byte[0];

            while (fileChannel.read(byteBuffer) != -1) {
                // 获取缓冲区位置,即读取长度
                int readSize = byteBuffer.position();

                // 将读取位置置0,并将读取位置标为废弃
                byteBuffer.rewind();

                // 读取内容
                byte[] readByte = new byte[readSize];
                byteBuffer.get(readByte);

                // 清除缓存区
                byteBuffer.clear();

                // 读取内容是否包含一整行
                boolean hasLF = false;

                int startNum = 0;

                for (int i = 0; i < readSize; i++) {
                    if (readByte[i] == ASCII_LF) {
                        hasLF = true;
                        int tempNum = temp.length;
                        int lineNum = i - startNum;

                        // 数组大小已经去掉换行符
                        lineByte = new byte[tempNum + lineNum];
                        System.arraycopy(temp, 0, lineByte, 0, tempNum);
                        temp = new byte[0];
                        System.arraycopy(readByte, startNum, lineByte, tempNum, lineNum);

                        String line = new String(lineByte, 0, lineByte.length, CHARSET_NAME);

                        content.add(line);

                        // 过滤回车符和换行符
                        if (i + 1 < readSize && readByte[i + 1] == ASCII_CR) {
                            startNum = i + 2;
                        } else {
                            startNum = i + 1;
                        }
                    }
                }
                if (hasLF) {
                    temp = new byte[readByte.length - startNum];
                    System.arraycopy(readByte, startNum, temp, 0, temp.length);
                } else {
                    // 单次读取的内容不足一行的情况
                    byte[] toTemp = new byte[temp.length + readByte.length];
                    System.arraycopy(temp, 0, toTemp, 0, temp.length);
                    System.arraycopy(readByte, 0, toTemp, temp.length, readByte.length);
                    temp = toTemp;
                }
            }

            // 最后一行
            if (temp.length > 0) {
                String lastLine = new String(temp, 0, temp.length, CHARSET_NAME);

                content.add(lastLine);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
       content.forEach(System.out::println);

    }

 JDK1.7 Files.readAllBytes

 public static void read(String path) throws IOException {

        byte[] bytes = Files.readAllBytes(Paths.get(path));

        String content = new String(bytes, StandardCharsets.UTF_8);
        System.out.println(content);
    }

 JDK1.8 Stream流

可能会出现内存溢出问题 java.lang.OutOfMemoryError

Files.lines

public static void read(String path) throws IOException {
        // 读取文件内容到Stream流中,按行读取
        Stream<String> lines = Files.lines(Paths.get(path));

        // 随机行顺序进行数据处理
        lines.forEach(System.out::println);
    }

forEach获取Stream流中的行数据不能保证顺序,但速度快。如果你想按顺序去处理文件中的行数据,可以使用forEachOrdered,但处理效率会下降。


lines.forEachOrdered(System.out::println);

或者利用CPU多和的能力,进行数据的并行处理parallel(),适合比较大的文件


lines.parallel().forEachOrdered(System.out::println);

Files.readAllLines

public static void read(String path) throws IOException {
    // 读取文件内容到Stream流中,按行读取
    List<String> lines =  Files.readAllLines(Paths.get(path),
            StandardCharsets.UTF_8);

    // 随机行顺序进行数据处理
    lines.forEach(System.out::println);
}

 JDK 11 Files.readString()

文件不能超过2G,同时要注意你的服务器及JVM内存。这种方法适合快速读取小文本文件。

     System.out.println(Files.readString(Paths.get(path))); 

依赖hutool

IoUtil工具类

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-core</artifactId>
    <version>5.8.10</version>
</dependency>

或者:
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.10</version>
</dependency>
 public static void read(String path) throws IOException {
        final String CHARSET_NAME = "UTF-8";


        List<String> content = new ArrayList<>();

        try {
            IoUtil.readLines(new FileInputStream(path), CharsetUtil.charset(CHARSET_NAME), content);
        } catch (Exception e) {
            e.printStackTrace();
        }
       content.forEach(System.out::println);

    }

 FileUtil工具类

public static void fileOfHutool() {
    
        final String CHARSET_NAME = "UTF-8";

        List<String> content = FileUtil.readLines(path, CHARSET_NAME);

        content.forEach(System.out::println);
      
    }

依赖cmmons-io

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>

FileUtils工具类

    public static void read(String path) throws IOException {
        final String CHARSET_NAME = "UTF-8";
        List<String> content = new ArrayList<>(0);

        try {
            content = FileUtils.readLines(new File(fileName), CHARSET_NAME);
        } catch (Exception e) {
            e.printStackTrace();
        }
       content.forEach(System.out::println);

    }

IOUtils工具类

public static void read(String path) throws IOException {
        final String CHARSET_NAME = "UTF-8";
        List<String> content = new ArrayList<>(0);
        try {
            content = IOUtils.readLines(new FileInputStream(fileName), CHARSET_NAME);
        } catch (Exception e) {
            e.printStackTrace();
        }
       content.forEach(System.out::println);

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值