> 文章列表 > [java]I/O

[java]I/O

[java]I/O

文章目录

    • 文件字节
      • 普通读取
      • 一次性读取
      • 跳过字节
      • 重新写入
      • 追加写入
      • 文件拷贝
    • 文件字符
    • File类
    • 缓冲流
    • 转换流
    • 打印流
    • 数据流
    • 对象流

文件字节流

普通读取

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:abcdtry(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:abcdtry(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:abcdtry(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"))) {   //传入FileInputStreamSystem.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)){  //将缓冲区大小设置为1bufferedInputStream.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)){  //将缓冲区大小设置为1bufferedInputStream.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;}}
}