[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: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;}}
}