文件字节流
普通读取
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; } } }