[java]I/O

简介: [java]I/O

文件字节流

普通读取

import java.io.FileInputStream;
import java.io.IOException;
public class Main {
    public static void main(String[] args) {
        try(FileInputStream inputStream = new FileInputStream("E:\\javapro\\por_1\\src\\test.txt")) {
            //使用read()方法进行字符读取
            System.out.println((char) inputStream.read());
            System.out.println(inputStream.read());
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    }
public static void main(String[] args) {
    //test.txt:abcd
    try(FileInputStream inputStream = new FileInputStream("test.txt")) {
        int tmp;
        while ((tmp = inputStream.read()) != -1){   //通过while循环来一次性读完内容
            System.out.println((char)tmp);
        }
    }catch (IOException e){
        e.printStackTrace();
    }
}

一次性读取

import java.io.FileInputStream;
import java.io.IOException;
public class Main {
    public static void main(String[] args) {
        //test.txt:abcd
        try(FileInputStream inputStream = new FileInputStream("test.txt")) {
            byte[] bytes = new byte[inputStream.available()];   //我们可以提前准备好合适容量的byte数组来存放
            System.out.println( inputStream.read(bytes));   //一次性读取全部内容(返回值是读取的字节数)
            System.out.println(new String(bytes));   //通过String(byte[])构造方法得到字符串
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    }

12

hello world!

跳过字节

import java.io.FileInputStream;
import java.io.IOException;
public class Main {
    public static void main(String[] args) {
        //test.txt:abcd
        try(FileInputStream inputStream = new FileInputStream("test.txt")) {
            System.out.println(inputStream.skip(4));
            System.out.println((char) inputStream.read());   //跳过了四个字节
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    }

4

o

重新写入

import java.io.FileOutputStream;
import java.io.IOException;
public class Main {
    public static void main(String[] args) {
        try(FileOutputStream outputStream = new FileOutputStream("output.txt")) {
            outputStream.write('c');   //同read一样,可以直接写入内容
            outputStream.write("lbwnb".getBytes());   //也可以直接写入byte[]
            outputStream.write("lbwnb".getBytes(), 2, 2);  //同上输入流
            outputStream.flush();  
            //建议在最后执行一次刷新操作(强制写入)来保证数据实时写入到硬盘文件中
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    }
clbwnbwn

追加写入

如果只想在文件尾部进行追加写入数据,跟上true即可

import java.io.FileOutputStream;
import java.io.IOException;
public class Main {
    public static void main(String[] args) {
        try(FileOutputStream outputStream = new FileOutputStream("output.txt",true)) {
            //true表示开启追加模式
            outputStream.write('c');   //同read一样,可以直接写入内容
            //现在只会进行追加写入,而不是直接替换原文件内容
            outputStream.flush();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    }

文件拷贝

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Main {
    public static void main(String[] args) {
        try(FileOutputStream outputStream = new FileOutputStream("output.txt");
            FileInputStream inputStream = new FileInputStream("test.txt")) {
            byte[] bytes = new byte[3];    //使用长度为3的byte[]做传输媒介
            int tmp;   //存储本地读取字节数
            while ((tmp = inputStream.read(bytes)) != -1){
                //直到读取完成为止
                outputStream.write(bytes, 0, tmp);
                //写入对应长度的数据到输出流
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    }

文件字符流

字符流是以一个具体的字符进行读取,因此它只适合读纯文本的文件,字符流只支持char[]类型作为存储

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Main{
    public static void main(String[] args) {
        try(FileReader reader = new FileReader("test.txt")){
            char[] str = new char[10];
            reader.read(str);
            System.out.println(str);   //直接读取到char[]中
        }catch (IOException e){
            e.printStackTrace();
        }
            try(FileWriter writer = new FileWriter("output.txt")){
                writer.getEncoding();   //支持获取编码(不同的文本文件可能会有不同的编码类型)
                writer.write('c');
                writer.append('苛').append("aaa");   //其实功能和write一样
                writer.flush();   //刷新
            }catch (IOException e){
                e.printStackTrace();
            }
        }
}

File类

import java.io.File;
public class Main{
    public static void main(String[] args) {
            File file = new File("test.txt");   //直接创建文件对象,可以是相对路径,也可以是绝对路径
            System.out.println(file.exists());   //此文件是否存在
            System.out.println(file.length());   //获取文件的大小
            System.out.println(file.isDirectory());   //是否为一个文件夹
            System.out.println(file.canRead());   //是否可读
            System.out.println(file.canWrite());   //是否可写
            System.out.println(file.canExecute());   //是否可执行
        }
        }

文件拷贝进度条

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Main {
    public static void main(String[] args) {
        File file=new File("colea.jpg");
        try(FileOutputStream outputStream = new FileOutputStream("cc.jpg");
            FileInputStream inputStream = new FileInputStream(file)) {
            byte[] bytes = new byte[1024];
            long total= file.length(),sum=0;
            int tmp;
            while ((tmp = inputStream.read(bytes)) != -1){
                outputStream.write(bytes, 0, tmp);
                sum+=tmp;
                System.out.println("文件已拷贝"+(sum*100/total)+'%');
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

缓冲流

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class Main {
    public static void main(String[] args) {
        try (BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("test.txt"))) {   //传入FileInputStream
            System.out.println((char) bufferedInputStream.read());   
            //操作和原来的流是一样的
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

调用mark()之后,输入流会以某种方式保留之后读取的readlimit数量的内容,当读取的内容数量超过readlimit则之后的内容不会被保留,当调用reset()之后,会使得当前的读取位置回到mark()调用时的位置。mark()后保存的读取内容是取readlimit和BufferedInputStream类的缓冲区大小两者中的最大值,而并非完全由readlimit确定。

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class Main {
    public static void main(String[] args) {
        try (BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("test.txt"), 1)){  //将缓冲区大小设置为1
            bufferedInputStream.mark(1);   //只保留之后的1个字符
            System.out.println((char) bufferedInputStream.read());
            System.out.println((char) bufferedInputStream.read());   //已经超过了readlimit,继续读取会导致mark失效
            bufferedInputStream.reset();   //mark已经失效,无法reset()
            System.out.println((char) bufferedInputStream.read());
            System.out.println((char) bufferedInputStream.read());
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class Main {
    public static void main(String[] args) {
        try (BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("test.txt"), 1)){  //将缓冲区大小设置为1
            bufferedInputStream.mark(2);   //只保留之后的1个字符
            System.out.println((char) bufferedInputStream.read());
//            System.out.println((char) bufferedInputStream.read());
            bufferedInputStream.reset();   //mark已经失效,无法reset()
            System.out.println((char) bufferedInputStream.read());
            System.out.println((char) bufferedInputStream.read());
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}

h

h

e

import java.io.*;
public class Main {
    public static void main(String[] args) {
        try (BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream("output.txt")))
        {
            outputStream.write("coleak".getBytes());
            outputStream.flush();
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}

缓冲字符流

缓冲字符流和缓冲字节流一样,也有一个专门的缓冲区,BufferedReader构造时需要传入一个Reader对象

import java.io.*;
public class Main {
    public static void main(String[] args) {
        try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))){
            System.out.println(reader.readLine());
            System.out.println(reader.readLine());//按行读取
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}
import java.io.*;
public class Main {
    public static void main(String[] args) {
        try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) {
            reader
                    .lines()
                    .limit(2)
                    .distinct()
                    .sorted()
                    .forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

把每一行内容依次转换为集合类提到的Stream流

转换流

public static void main(String[] args) {
    try(InputStreamReader reader = new InputStreamReader(new FileInputStream("test.txt"))){  //虽然给定的是FileInputStream,但是现在支持以Reader的方式进行读取
        System.out.println((char) reader.read());
    }catch (IOException e){
        e.printStackTrace();
    }
}
public static void main(String[] args) {
    try(OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("test.txt"))){  
        //虽然给定的是FileOutputStream,但是现在支持以Writer的方式进行写入
        writer.write("lbwnb");   //以操作Writer的样子写入OutputStream
    }catch (IOException e){
        e.printStackTrace();
    }
}

打印流

import java.io.*;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        try(PrintStream stream = new PrintStream(new FileOutputStream("test.txt"))){
            Scanner scanner = new Scanner(System.in);
            String a=scanner.next();
            stream.println(a);   //其实System.out就是一个PrintStream
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

数据流

数据流DataInputStream也是FilterInputStream的子类,同样采用装饰者模式,最大的不同是它支持基本数据类型的直接读取

import java.io.*;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        try (DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream("output.txt"))){
            dataOutputStream.writeBoolean(false);
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}

对象流

对象的序列化操作,以某种格式保存对象,来支持对象类型的IO

import java.io.*;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        try (ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("output.txt"));
             ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("output.txt"))){
            People people = new People("coleak");
            outputStream.writeObject(people);
            outputStream.flush();
            people = (People) inputStream.readObject();
            System.out.println(people.name);
        }catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    static class People implements Serializable{   //必须实现Serializable接口才能被序列化
        String name;
        public People(String name){
            this.name = name;
        }
    }
}
static class People implements Serializable{
    private static final long serialVersionUID = 123456;   
    //在序列化时,会被自动添加这个属性,它代表当前类的版本,我们也可以手动指定版本。
    String name;
    public People(String name){
        this.name = name;
    }
}

transient关键字

import java.io.*;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        try (ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("output.txt"));
             ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("output.txt"))){
            People people = new People("lbw");
            outputStream.writeObject(people);
            outputStream.flush();
            people = (People) inputStream.readObject();
            System.out.println(people.name);  //虽然能得到对象,但是name属性并没有保存,因此为null
        }catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    static class People implements Serializable{
        private static final long serialVersionUID = 1234567;
        transient String name;
        public People(String name){
            this.name = name;
        }
    }
}


目录
相关文章
|
3月前
|
存储 监控 Java
Java输入输出:什么是NIO(New I/O)?
Java输入输出:什么是NIO(New I/O)?
50 1
|
2月前
|
存储 缓存 Java
Java中的缓冲流提升I/O性能,通过内存缓冲区减少对硬件访问
【6月更文挑战第22天】Java中的缓冲流提升I/O性能,通过内存缓冲区减少对硬件访问。`BufferedInputStream`和`BufferedOutputStream`用于字节流,缓存数据批量读写。`BufferedReader`和`BufferedWriter`处理字符流,支持按行操作。使用后务必关闭流。
31 3
|
3月前
|
存储 监控 Java
深入探索Java语言的NIO(New I/O)技术
深入探索Java语言的NIO(New I/O)技术
|
1月前
|
存储 缓存 Oracle
可能是最漂亮的Java I/O流详解
大家有什么思路吗?评论区一起讨论讨论。我需要使用 Java 逐行读取大约 5-6 GB 的大型文本文件。我怎样才能快速完成此操作?最高赞的回答是叫Peter Lawrey的老哥回答的。大家好,我是南哥。一个Java学习与进阶的领路人,今天指南的是Java I/O流,跟着南哥我们一起在Java之路上成长。本文收录在我开源的《Java学习进阶指南》中,涵盖了想要学习Java、成为更好的Java选手都在偷偷看的核心知识、面试重点。
可能是最漂亮的Java I/O流详解
|
29天前
|
Java Linux
Java演进问题之1:1线程模型对于I/O密集型任务如何解决
Java演进问题之1:1线程模型对于I/O密集型任务如何解决
|
1月前
|
Java API 开发者
Java中的文件I/O操作详解
Java中的文件I/O操作详解
|
1月前
|
Java 数据库
Java面试题:请解释Java中的输入输出(I/O)流?详细说明应用场景
Java面试题:请解释Java中的输入输出(I/O)流?详细说明应用场景
16 0
|
2月前
|
Java 视频直播 数据库连接
Java I/O 模型详解:BIO、NIO 与 AIO 的特性与应用
Java I/O 模型详解:BIO、NIO 与 AIO 的特性与应用
40 2
|
2月前
|
存储 网络协议 Java
Java I/O 详解:基础、文件操作与 NIO 实践
Java I/O 详解:基础、文件操作与 NIO 实践
26 1
|
1月前
|
Java API 开发者
Java中不同I/O操作的性能比较
Java中不同I/O操作的性能比较