IO流


网图
看JDK文档更清晰
看JDK文档更清晰
看JDK文档更清晰
看JDK文档更清晰
原理
参考博文(https://blog.csdn.net/sinat_37064286/article/details/86537354)详细
所谓的输出流和输入流是相对于代码程序而言的
- 输入流:从别的地方(本地文件,网络上的资源等)获取资源 输入到 我们的程序中
- 输出流:从我们的程序中 输出到 别的地方(本地文件), 将一个字符串保存到本地文件中,就需要使用输出流。
根据处理单位又分为字符流和字节流
- 1字符 = 2字节 、 1字节(byte) = 8位(bit) 、 一个汉字占两个字节长度 。
按功能不同分为 节点流、处理流
4个基本的抽象流类型,所有的流都继承这四个
输入流 输出流
字节流 InputStream outputStream
字符流 Reader Writer
字符流的由来: Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此,JAVA中引入了处理字符的流。因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。
字符输出流
部分类:
FileWriter
用来写入字符文件的便捷类
public class Test1 { public static void main(String[] args) throws Exception { FileWriter fileWriter=new FileWriter("A/testA11",true); //如果没有这个文件的话就自动新建,true表示追加,而不是覆盖原有数据 String str1="asdfghjkl/"; fileWriter.append(str1); fileWriter.flush(); // 刷新该流的缓冲 //fileWriter.close(); //先强制刷新缓存,在关闭 使用流必须要关闭 buffW(); }
BufferedWriter
将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
//BufferedWriter(Writer out) //创建一个使用默认大小输出缓冲区的缓冲字符输出流。 //BufferedWriter(Writer out, int sz) //创建一个使用给定大小输出缓冲区的新缓冲字符输出流。 /** * BufferedWriter 简单使用,建议看文档 * @throws Exception */ static void buffW() throws Exception { FileWriter fileWriter=new FileWriter("A/testA11"); BufferedWriter bufferedWriter=new BufferedWriter(fileWriter); char[] chars={'1','2','3','4','5','6','7'}; for (int i=0;i<3;i++){ bufferedWriter.write(chars,0,chars.length); //写入缓存, bufferedWriter.newLine(); //写入一个行终止,也就是换行 bufferedWriter.write('i'); //再写入 bufferedWriter.newLine(); bufferedWriter.flush(); } bufferedWriter.close(); // 1234567 // i // 1234567 // i // 1234567 // i }
CharArrayReader
此类实现一个可用作 Writer 的字符缓冲区。缓冲区会随向流中写入数据而自动增长。
在此类上调用 close() 无效,并且在关闭该流后可以调用此类中的各个方法,而不会产生任何 IOException。
例子
static void charAW() throws Exception { ///FileWriter fileWriter=new FileWriter("A/testA11"); CharArrayWriter charArrayWriter=new CharArrayWriter(); for (int i=0;i<3;i++){ // System.out.println(charArrayWriter.append(String.valueOf(i))); 0 01 012 charArrayWriter.append(String.valueOf(i)); } charArrayWriter.close(); //没有用,charArrayWriter还是可以正常使用 charArrayWriter.write('a'); System.out.println(charArrayWriter.toString()); //012a String类型 System.out.println(charArrayWriter.toCharArray()); // 012a char[]类型 System.out.println("重置前"+charArrayWriter.size()); //重置前4 //那close()没用,缓存满了怎么办呢 charArrayWriter.reset(); //缓存重置 System.out.println("重置后"+charArrayWriter.size()); // 重置后0 }
FilterWriter
PrintWriter
向文本输出流打印对象的格式化表示形式。此类实现在 PrintStream 中的所有 print方法。它不包含用于写入原始字节的方法,对于这些字节,程序应该使用未编码的字节流进行写入。
与 PrintStream 类不同,如果启用了自动刷新(换行),则只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作,而不是每当正好输出换行符时才完成。
例子
static void priW() throws Exception { //FileWriter fileWriter = new FileWriter("A/testA11"); //PrintWriter printWriter = new PrintWriter(fileWriter); PrintWriter printWriter = new PrintWriter("A/testA11"); for (int i = 0; i < 3; i++) { printWriter.println("数据" + i); //数据0 //数据1 //数据2 } printWriter.close(); }
字符输入流
部分类:
FileReader
用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。
例子
static void filS() throws Exception { FileReader fileReaderA = new FileReader("A/testA11"); char[] ch = new char[1024]; while ((fileReaderA.read(ch)) != -1) { } System.out.println(ch); fileReaderA.close(); }
BufferedReade
从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
建议用 BufferedReader 包装所有其 read() 操作可能开销很高的 Reader(如 FileReader 和 InputStreamReader)
例子
static void buffS() throws Exception { FileReader fileReader = new FileReader("A/testA11"); FileWriter fileWriter = new FileWriter("B/testB1"); BufferedReader bufferedReader = new BufferedReader(fileReader); BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); char[] ch = new char[1024]; String ch1; //bufferedReader.skip(2); //要跳过几个字符 //while ((bufferedReader.read(ch))!=-1){ //复制文件内容 A/testA11》》B/testB1 while ((ch1 = bufferedReader.readLine()) != null) { fileWriter.append( ch1); fileWriter.flush(); } //System.out.println(ch); //数据0 //数据1 //数据2 fileReader.close(); fileWriter.close(); }
字节输入流
部分类:
- FileInputStream
- FileInputStream从文件系统中的某个文件中获得输入字节。
- v
字节输出流
部分类:
FileOutputStream
文件输出流是用于将数据写入 File或 FileDescriptor 的输出流。
例子
static void onpS() throws Exception { FileOutputStream fileOutputStream=new FileOutputStream("A/testA11"); byte[] ch={'a','b','c','d','e','f','g'}; fileOutputStream.write(ch); fileOutputStream.close(); }
h
File
文件和目录路径名的抽象表示形式。
例子
static void file() throws Exception { File file1=new File("B/C/c/v"); File file2=new File("B/s"); File file=new File("C/v/testA12.txt"); File file3=new File("A/testA12.txt"); //file2.mkdir(); //单级(一个目录) //file1.mkdirs(); //在B目录下创建新目录C 多级 //如果指定的文件不存在并成功地创建,则返回 true;如果指定的文件已经存在,则返回 false //目录是已存在的,如果路径是不存在的会报异常(系统找不到指定的路径。) // file.createNewFile(); // System.out.println(File.separatorChar); // separator 同功能,返回类型不同;与系统有关的默认名称分隔符。 // System.out.println(File.pathSeparatorChar); // pathSeparator ; 与系统有关的路径分隔符。 // System.out.println(file.getName()); //获取文件名(包括后缀) // System.out.println(file.getParent()); // C\v 返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。 // System.out.println(file.getAbsoluteFile()); //获取文件绝对路径 // System.out.println(file.getPath()); //C\v\testA12.txt 将此抽象路径名转换为一个路径名字符串。所得字符串使用 默认名称分隔符分隔名称序列中的名称 // System.out.println(file.isAbsolute()); //测试此抽象路径名是否为绝对路径名 // System.out.println(file.isDirectory()); //测试此抽象路径名表示的文件是否是一个目录 // System.out.println(file.isFile()); //测试此抽象路径名表示的文件是否是一个标准文件 // System.out.println(file.isHidden()); // 测试此抽象路径名指定的文件是否是一个隐藏文件 // File file41=new File("A/testA1"); // File file42=new File("A/testA122");//相差2位 // // //按字母顺序比较两个抽象路径名 // //如果该参数等于此抽象路径名,则返回零; // // 如果此抽象路径名在字母顺序上小于该参数,则返回小于零的值; // //如果此抽象路径名在字母顺序上大于该参数,则返回大于零的值 // System.out.println(file41.compareTo(file42)); //-2 // String pattern = "yyyy-MM-dd HH:mm:ss"; // //文件最后一次被修改的时间 // //2021-05-04 14:14:12 // System.out.println(new SimpleDateFormat(pattern).format(new Date(file3.lastModified()))); //返回由此抽象路径名表示的文件的长度 ,以字节为单位 System.out.println(file3.length()); //123456我 返回9 包括结束符 }
序列化与反序列化
static void obj() throws Exception {
A a = new A();
a.setId(1);
a.setName("张三");
a.setAge(23);
A a2 = new A(2, "李四", 22);
A a21 = new A(3, "李五", 23);
A a22 = new A(4, "李六", 24);
//序列化
// ObjectOutputStream objectOutputStream=new ObjectOutputStream(new FileOutputStream("A/testA12.txt"));
// objectOutputStream.writeObject(a);
// objectOutputStream.writeObject(a2);
// objectOutputStream.writeObject(a21);
// objectOutputStream.writeObject(a22);
// objectOutputStream.close();
//反序列化
FileInputStream fileInputStream=new FileInputStream("A/testA12.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
// A aa = (A) objectInputStream.readObject();
//
// A aa1 = (A) objectInputStream.readObject();
A aa =null;
for (int i=0;i<fileInputStream.available();i++){
aa = (A) objectInputStream.readObject();
System.out.println(aa.toString());
aa=null;
}
objectInputStream.close();
}
///要序列化的类
//实现Serializable接口
class A implements Serializable {
private Integer id;
private String name;
private Integer age;
public A() {
}
public A(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "A{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
transient 不需要序列化的属性使用关键字
好像忘了写什么?想不起来了