韩顺平Java37——IO流(目前有点乱,日后整理)
IO流
1.基本概念
1.1文件
1.2文件流
流是针对内存来说的,输入输出也是以内存为基本点来说的
2.常用的文件操作
2.1创建文件相关方法
演示:
package newfile; import org.junit.jupiter.api.Test; import java.io.File; import java.io.IOException; /** * @author 紫英 * @version 1.0 * @discription 创建文件 */ public class FileCreate { private String parentPath; public static void main(String[] args) { } @Test public void create01() { //第一种方式 new File(String pathname) 根据路径构建一个File对线 String filePath = "C:\\Users\\MI\\Desktop\\file01.txt"; File file = new File(filePath); try { file.createNewFile();//此时真正创建文件 System.out.println("文件“file01.txt”创建成功"); } catch (IOException e) { e.printStackTrace(); } } @Test public void create02() { //第二种方式 new File(File parent, String child) File parentFile = new File("C:\\Users\\MI\\Desktop"); String fileName = "file02.txt"; File file = new File(parentFile, fileName);//此时的file还只是一个对象 try { file.createNewFile();//file.createNewFile()过后file02.txt文件才真正在硬盘中创建起来 System.out.println("文件“file02.txt”创建成功"); } catch (IOException e) { e.printStackTrace(); } } @Test public void create03(){ //第三种方式 new File(String parent, String child) parentPath = "C:\\Users\\MI\\Desktop"; String fileName = "file03.txt"; File file = new File(parentPath, fileName); try { file.createNewFile(); System.out.println("文件“file03.txt”创建成功"); } catch (IOException e) { e.printStackTrace(); } } }
可以看到确实在桌面上创建了三个文件
2.2获取文件相关信息
length是文件大小(字节)
演示:
package newfile; import java.io.File; import java.io.IOException; /** * @author 紫英 * @version 1.0 * @discription 查看文件信息方法 */ public class Fileinfo { public static void main(String[] args) { File file = new File("C:\\Users\\MI\\Desktop\\file01.txt"); try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } //调用相应的方法,得到对应信息 System.out.println("文件名字=" + file.getName()); //getName、getAbsolutePath、getParent、length、exists、isFile、 isDirectory System.out.println("文件绝对路径=" + file.getAbsolutePath()); System.out.println("文件父级目录=" + file.getParent()); System.out.println("文件大小(字节)=" + file.length()); System.out.println("文件是否存在=" + file.exists());//T System.out.println("是不是一个文件=" + file.isFile());//T System.out.println("是不是一个目录=" + file.isDirectory());//F } }
往文件里写了“666”
2.3目录的操作和文件删除
注意在Java编程中目录也被当作一种文件
演示:
package newfile; import org.junit.jupiter.api.Test; import java.io.File; import java.io.IOException; /** * @author 紫英 * @version 1.0 * @discription 目录操作 */ public class Directory { @Test public void m1() { //判断文件是否存在,如果存在就删除 File file = new File("C:\\Users\\MI\\Desktop\\file01.txt"); if (file.exists()) { if (file.delete()) {//既是条件又是语句 System.out.println("删除成功!"); } else { System.out.println("删除失败!"); } } else { System.out.println("文件不存在!"); } }
@Test public void m2() { //判断目录是否存在,如果存在就删除 //注意在Java编程中目录也被当作一种文件 String dirPath = "C:\\Users\\MI\\Desktop\\aaa"; File file = new File(dirPath); if (file.exists()) { if (file.delete()) {//既是条件又是语句 System.out.println("删除成功!"); } else { System.out.println("删除失败!"); } } else { System.out.println("目录不存在!"); } }
@Test public void m3() { //判断目录是否存在,如果不存在就创建 //想创建单级目录就用mkdir() // 多级用mkdirs() 比如"C:\\Users\\MI\\Desktop\\aaa\\bbb\\ccc"就会创建三级目录 //单级目录不能用mkdirs()反之亦然 String dirPath = "C:\\Users\\MI\\Desktop\\aaa"; File file = new File(dirPath); if (file.exists()) { System.out.println("目录已存在"); } else { if (file.mkdir()) { System.out.println("创建成功!"); } else { System.out.println("创建失败!"); } System.out.println("目录不存在!"); } } }
3.IO流原理及流的分类
3.1 IO流原理
3.2流的分类
- 注意:
1.采用字符流传输的效率更高,但是在传输一些二进制文件(例如音频、视频)时使用字节流可以保证无损操作。
2.文本文件使用字符流比较好
3.这四个基本类都是抽象类
体系图:
流与文件关系类比:
4.常用类分析——InputSteam(字节输入流)
InputStream抽象类是所有类字节输入流的父类
4.1FileInputStream
- 构造方法
- 方法
两种read()方法演示:
package inputsteam; import org.junit.jupiter.api.Test; import java.awt.*; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; /** * @author 紫英 * @version 1.0 * @discription 两种read方法演示 */ public class Fileinput { @Test public void m1() throws FileNotFoundException { //第一种方式——使用read一个字节一个字节地读取 FileInputStream fileInputStream = new FileInputStream("C:\\Users\\MI\\Desktop\\file02.txt"); int readData = 0; try { while ((readData = fileInputStream.read()) != -1) { //read方法功能:读取单个字节,返回该字节的码值。如果读到文件末尾,返回-1 System.out.print((char) readData);//循环输出单个字节 并转成char类型显示 } } catch (IOException e) { e.printStackTrace(); } finally { try { //关闭文件流 释放资源 fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } @Test public void m2() throws FileNotFoundException { //第二种方式——使用read按照byte数组来读 FileInputStream fileInputStream = new FileInputStream("C:\\Users\\MI\\Desktop\\file02.txt"); int readLen = 0; byte[] b = new byte[8];//创建一个8位数组一次性读八个 try { while ((readLen=fileInputStream.read(b)) != -1) { //read(byte[] b)方法返回值——实际读取的字节数。如如果读取完毕,返回-1 //这里用readLen来保存返回值,以确保字符串的顺利输出 System.out.print(new String(b,0,readLen));//将数组封装成字符串输出 } } catch (IOException e) { e.printStackTrace(); } finally { try { //关闭文件流 释放资源 fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }
debug一下可以看到:第一次返回值是8,第二次是5
4.FileOutputStream
将字符串转为byte[]数组的方法
另一种写入方式
注意:
IO流实现文件拷贝
演示:
package inputsteam; import java.io.*; /** * @author 紫英 * @version 1.0 * @discription 文件拷贝 */ public class FileCopy { public static void main(String[] args) { int readLen; byte[] bytes = new byte[1024]; FileInputStream in = null;//创建流对象 FileOutputStream out = null; try { in = new FileInputStream("C:\\Users\\MI\\Desktop\\file02.txt");//文件写入对象 out = new FileOutputStream("C:\\Users\\MI\\Desktop\\file02copy.txt"); while ((readLen=in.read(bytes))!=-1){ //一边读一边写 out.write(bytes,0,readLen); } } catch (IOException e) { e.printStackTrace(); }finally { //关闭流释放资源 try { in.close(); out.close(); } catch (IOException e) { e.printStackTrace(); } } } }
注意:
FileWriter使用后一定要使用close()关闭,否则不会真正写入到文件
节点流和处理流
节点流:针对某一种特定的数据源(比较底层)
处理流: 内部封装了一个对应的Reader或者Writer等父类的对象,可以对节点流进行操作,更加灵活
- 修饰器设计模式代码模拟:
package bufferedreader01; /** * @author 紫英 * @version 1.0 * @discription 修饰器设计模式模拟 */ public class Bufferreader_ extends Reader_ { private Reader_ in; //封装一个Reader类型的对象 public Bufferreader_(Reader_ in) { this.in = in; } @Override void read() { in.read(); //利用动态绑定机制 } } abstract class Reader_ { abstract void read(); } class FileReader_ extends Reader_ { @Override void read() { System.out.println("文件读取..."); } } class StringReader_ extends Reader_ { @Override void read() { System.out.println("字符串读取..."); } }
测试:
package bufferedreader01; /** * @author 紫英 * @version 1.0 * @discription */ public class Test { public static void main(String[] args) { Bufferreader_ bufferreader_ = new Bufferreader_(new FileReader_()); bufferreader_.read(); Bufferreader_ bufferreader_1 = new Bufferreader_(new StringReader_()); bufferreader_1.read(); } }
字符处理流
这里的外层流即处理流
bufferedreader代码演示:
bufferedwriter代码演示:
filewriter追加or覆盖:
字节处理流
第二种构造方法说明一下:
size指定的是下图中byte [] buf的大小:可以看到默认是8192,如果加了就是按照指定大小,就是一次性读取多少个字节存到我们创建的byte[]类型数组中
如果buf的大小超过了我们创建的,比如指定buf大小为8,创建的为4,则先读取8个,分两次写入(一次写4个)
因为按照这种传参方式,写入个数还是以我们创建的数组大小为准
序列化和反序列化——对象流
这两个类仍然属于处理流
代码演示:
- 写入:
package outputsteam; import inputsteam.Dog; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; /** * @author 紫英 * @version 1.0 * @discription 对象流实现序列化写入 */ public class Objwrite { public static void main(String[] args) throws IOException { ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("C:\\Users\\MI\\Desktop\\data.data")); objectOutputStream.writeInt(100); objectOutputStream.writeBoolean(true); objectOutputStream.writeUTF("卡机还是给丢啊伟大hi"); 这里注意如果读取用的readUTF写入最好也用 不然容易出错 objectOutputStream.writeObject(new Dog("旺财",2)); objectOutputStream.close(); System.out.println("序列化写入完毕!"); } }
注意写入的对象需要实现序列化接口否则会编译报错!
- 读取:
package inputsteam; import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream; /** * @author 紫英 * @version 1.0 * @discription 对象流实现反序列化读取 */ public class Objin { public static void main(String[] args) throws IOException, ClassNotFoundException { ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("C:\\Users\\MI\\Desktop\\data.data")); System.out.println(objectInputStream.readInt()); System.out.println(objectInputStream.readBoolean()); String s = null; s = objectInputStream.readUTF(); System.out.println(s); Object dog = objectInputStream.readObject(); System.out.println(dog); objectInputStream.close(); System.out.println("反序列化读取完毕!"); } }
细节:
说明 3)
private static final long serialVersionUID = 1L; 加了这个在对类进行修改后序列化的时候不会认为是一个新类,而会认为是当前类的不同版本
5)
如果一个类中有一个属性是另一个类,则要求另一个类也要实现序列化接口
标准输入输出流
转换流
ANSI是国标码 对应到中文系统是GBK
reader代码演示:
writer代码演示:
打印流
注意打印流只有输出流
字节打印流:
字符打印流:
代码演示:
本文来自博客园,作者:紫英626,转载请注明原文链接:https://www.cnblogs.com/recorderM/p/15851726.html