文件目录结构
注:io流的操作 基本都是固定的 1.实例化节点0流 2.实例化处理流3.数据的操作4.流的关闭
import org.junit.jupiter.api.Test; import java.io.File; import java.io.IOException; import java.util.Date; //file 指文件 或 文件目录 俗称文件夹 //相对路径 从module下开始 //分隔符 windows dos “/” unix:\ 详情可参考file中的separator public class FileTest { @Test public void InstantiateFile() { //创建file方式一 File(filepath) //此时只是创建一个内存对象 并未操作 File file1 = new File("hello.txt"); File file2 = new File("E:\\Jdbc\\IOTe\\he.txt"); // System.out.println(file1); // System.out.println(file2); //构造器2 File(String parent, String child) File file3 = new File("E:\\Jdbc\\","IOTe"); System.out.println(file3); //构造器3 (File parent, String child) File file4 = new File(file3,"h.txt"); // System.out.println(file4); } @Test public void CommonMethod1(){ //常用方法 File file = new File("hello.txt"); //绝对路径 System.out.println(file.getAbsoluteFile()); //是否可读 System.out.println(file.canRead()); //是否可写 System.out.println(file.canWrite()); //获取名字 System.out.println(file.getName()); //获取相对路径 System.out.println(file.getPath()); //获取上层路径 若无 返回null 因为是相对路径 所以是null System.out.println(file.getParent()); System.out.println(file.getParentFile()); //获取文件长度 字节数 不能获取目录 System.out.println(file.length()); //最后一次的修改时间 毫秒值 System.out.println(new Date(file.lastModified())); } @Test public void CommonMethod2(){ //关于文件目录的方法 //目录必须存在 File file = new File("E:\\Java"); String[] list = file.list(); for (String s: list) { System.out.println(s); } //列出全路径 System.out.println(); System.out.println(); File[] file1 = file.listFiles(); for (File f: file1) { System.out.println(f); } } @Test public void ParticularMethod(){ //特殊方法renameTo:public boolean renameTo(File dest) 将文件一的内容复制到文件二当中 File f1 = new File("hello.txt");//文件1必须存在 File f2 = new File("hi.txt");//文件2必须不存在,存在即false boolean b = f1.renameTo(f2); System.out.println(b); } @Test public void JudgeMethod(){ //常见的判断方法 File file = new File("hello.txt"); //判断是否是文件目录 System.out.println(file.isDirectory()); //判断是否是文件 System.out.println(file.isFile()); //判断是否存在 System.out.println(file.exists()); //是否可读 System.out.println(file.canRead()); //是否可写 System.out.println(file.canWrite()); //是否可隐藏 System.out.println(file.isHidden()); } @Test public void CreateFile() throws IOException { //创建硬盘中对应的文件或文件目录 本身就存在 不创建并返回false //file类的创建、删除、重命名、修改时间等方法均需抛异常,且file不存在修改文件的内容等操作 //修改内容等操作需要用到IO流去操作 File file = new File("a.txt"); System.out.println(file.createNewFile()); File directory = new File("D:\\file"); //文件上层目录存在创建,不存在则不创建 System.out.println(directory.mkdir()); //文件上层目录存在创建,不存则一并创建 System.out.println(directory.mkdirs()); } }
public class FileReaderTest { @Test public void test1() { //为了一定能关闭流的操作,要用try catch FileReader fr = null; try { //1.file 的实例化 指出操纵的对象 File f = new File("hi.txt"); //2.提供具体的流 fr = new FileReader(f); //3.数据的读入 read()返回读入的一个字符,到达末尾返回-1. int data = fr.read(); //返回的是unicode码 即a=97 所以下面用到转换 while (data != -1) { System.out.print((char) data); data = fr.read(); } } catch (IOException e) { e.printStackTrace(); } finally { try { //这个是防止fr在实例化时失败,即没有fr对象 assert fr != null; fr.close(); } catch (IOException e) { e.printStackTrace(); } } //4.流的关闭操作 //对于jvm的垃圾回收功能 数据库连接 输入输出流 Socket连接 jvm回收不了, //需要手动关闭 } @Test public void test2() { //read() 进阶版 FileReader fr = null; try { File f = new File("hi.txt"); fr = new FileReader(f); //read(char[] cb):返回每次读入cb数组中字符的个数 如果读到最后一个值返回-1 char[] cb = new char[5]; int len; while ((len = fr.read(cb)) != -1) { /* 错误的写法 说明存入数据的时候是一个一个存的 而并非一次性存满整个数组 方式一 for (char c : cb) { System.out.print(c); } 结果guess234ss 方式二 String str = new String(cb); System.out.println(str); */ //正确的 即读进去几个就遍历几个 //方式一 // for (int i = 0; i <len ; i++) { // System.out.print(cb[i]); // } //方式二 //从0开始读每次读len个 String str = new String(cb,0,len); System.out.print(str); //结果guess234 } } catch (IOException e) { e.printStackTrace(); } finally { if (fr != null) { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } } //read(char cb[], int off, int len) //reed 的三个参数的方法 比如cb的长度是5,但是在存入的时候存放len个长度 }
public class FileWriterTest { @Test //1.写入的操作中,允许文件不存在,如果不存在则在输出的过程直接进行创建 //2.如果本身文件就存在: // (1):writer(file)/writer(file,false) 则会对原文件进行覆盖 // (2):writer(file,true)则会对原文件进行追加内容 public void test1() throws IOException { //1.file 的实例化 File f = new File("hello.txt"); //2.FileWrite的实例化 FileWriter fw = new FileWriter(f); //3.对数据进行操作 fw.write("Position"); fw.write("You can see ?"); //4.进行资源的关闭 fw.close(); } @Test public void copy() throws Exception { //1.实例化file File file = new File("hi.txt"); File fl = new File("hi1.txt"); //2.创建输入输出流对象 FileReader fr = new FileReader(file); FileWriter fw = new FileWriter(fl, true); //3.操作数据 char[] cb = new char[5]; int len; while ((len = fr.read(cb)) != -1) { //我的里面8个字符 第一次len=5,第二次len=3 String str = new String(cb, 0, len); fw.write(str, 0, len); } //4.资源关闭 fw.close(); fr.close(); } }
public class FileInputOutputStream { @Test public void copyImg() { //注 字节流可以可以拿来复制文本文件的东西 在内存层面读可能会出出现乱码,但是复制好之后不会出现乱码 //数组的长度,不同长度 影响读取的速度 并非越大越好 FileOutputStream fos = null; FileInputStream fis = null; try { //1.实例化file 注意路径符\\ File file1 = new File("src\\img\\1.png"); File file2 = new File("2.png"); //2.实例化流 fos = new FileOutputStream(file2); fis = new FileInputStream(file1); //3.操作数据 byte[] by = new byte[5]; int len; while((len=fis.read(by)) != -1){ fos.write(by,0,len); } } catch (IOException e) { e.printStackTrace(); }finally { //流的关闭 if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
public class Buffer1 { @Test public void copyImgPlus() throws IOException { //1.实例化file File file1 = new File("src\\img\\1.png"); File file2 = new File("3.png"); //2.创建节点流 FileInputStream fis = new FileInputStream(file1); FileOutputStream fos = new FileOutputStream(file2); //3.创建处理流 处理流就是套接在节点流之上 //缓冲流作用 增加读写速度(原因是因为内部提供了一个缓冲区) BufferedInputStream bis = new BufferedInputStream(fis); BufferedOutputStream bos = new BufferedOutputStream(fos); //bis.flush;刷新缓冲区,Java后台自动刷新所以不用写 //4.操作数据 byte[] by = new byte[5]; int len; while ((len=bis.read(by)) != -1){ bos.write(by,0,len); } //5.流的关闭 先关外层的再关内层的 关闭外层流的同时,内层流也会自动关闭 // 然后 try catch 快捷建 Alt Shift z bos.close(); bis.close(); } @Test public void copyPlus() { //用匿名对象 实例化file 实例化流 BufferedReader br = null; BufferedWriter bw = null; try { br = new BufferedReader(new FileReader(new File("hi.txt"))); bw = new BufferedWriter(new FileWriter(new File("hi1.txt"))); //操作数据 方式一 // char[] cr = new char[5]; // int len; // while ((len=br.read(cr)) != -1){ // bw.write(cr,0,len); // }方式二 缓冲流里有直接读取一行的方法 String data; while((data=br.readLine()) !=null){ // bw.write(data); 此时数据没有换行 //加换行符 或者直接 bw.newline() bw.write(data+"\n"); } } catch (IOException e) { e.printStackTrace(); } finally { //流的关闭 if (bw != null) { try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Test //加密操作 public void encrypt() { //实例化 FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream("24.png"); // public FileInputStream(String name) 有这个形参 所以直接可以放文件路径 fos = new FileOutputStream("28.png"); //操作数据 byte[] bt = new byte[10]; int len; while ((len=fis.read(bt)) != -1){ //主要就是进行异或运算 两次异或之后就得到了原来的文件 for (int i = 0; i < len; i++) { bt[i] = (byte) (bt[i] ^ 2); } fos.write(bt,0,len); } } catch (IOException e) { e.printStackTrace(); }finally { //流的关闭 if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
public class ChangeStream { //转换流 //InputStreamReader 将字节的输入流转换为字符的输入流 //OutputStreamWriter 将字符的文件 转换为字节的文件 //作用 实现流之间的转换 // 解码 字节——>字符 编码 字符->字节 @Test public void changeOut() throws IOException { //1.实例化流 节点流 FileInputStream fis = new FileInputStream("hi.txt"); //2.实例话处理流(处理流) InputStreamReader isr = new InputStreamReader(fis,"utf-8"); //次方法有 只有一个参数 参数为节点流对象 默认为的字符集是编译软件所设置的 两个参数的 第二个参数为文件保存时的字符集 //3.操作数据 char[] ca = new char[5]; int len; while ((len= isr.read(ca)) != -1){ for (int i = 0; i < len; i++) { System.out.print(ca[i]); } } //4.流的关闭 容易观看 未用try catch } @Test public void changeInOut() throws Exception { //用字节流读取utf-8格式的文件 再以 gbk的形式输出 FileInputStream fis = new FileInputStream("hi.txt"); InputStreamReader isr = new InputStreamReader(fis); FileOutputStream fos = new FileOutputStream("hi_gbk.txt"); OutputStreamWriter osw = new OutputStreamWriter(fos,"gbk"); char[] ca = new char[5]; int len; while ((len= isr.read(ca)) != -1){ osw.write(ca,0,len); } isr.close(); osw.close(); } }
public class ObjectStream { //ObjectInputStream ObjectOutputStream //作用 用于存储和读取基本类型的数据或对象的处理流 持久化Java中的数据 @Test public void xlh() throws Exception { //序列化 过程:将内存层面的数据存到磁盘中或者进行网络传输 ObjectOutputStream //1.创建一个序列化对象 后缀名可以随意,因为不是用来给我们看的 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("result.sj")); //2.把对象写进去 String s="我是最帅的"; oos.writeObject(s); oos.flush(); //刷新操作 oos.writeObject(new Teacher(99,"帅B")); oos.flush(); //3.关闭流 记得try catch finally alt shift z oos.close(); } @Test public void reverseXlh() throws Exception { //反序列化 就是把序列化的数据还原到内存层面 //1.创建反序列化对象 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("result.sj")); //2.把对象读出来 String s = (String) ois.readObject(); Teacher teacher = (Teacher) ois.readObject(); //测试数据是否读出 System.out.println(s); System.out.println(teacher); //3.关闭流 记得try catch finally alt shift z ois.close(); } }
注:关于序列化
public class Teacher implements Serializable { //要想序列化一个对象 需要满足的条件 //1.继承 Serializable接口(该接口并没有具体的方法(这样的接口一般叫做标识)) //2.实例化一个常量 serialVersionUID = 42L //3.注 static transient 修饰的成员变量不能序列化 //特殊: 当你所序列化的对象中含有其他对象属性没继承Serializable接口 也会出现问题 //解决: 把其他对象也实现此接口并赋予一个值serialVersionUID private int id; private String name; //自己随便写一个 long类型的 如果未写 会自动生成 不过当再次修改之后再进行反序列化会出现一些问题 //作用 就是标识 就像身份证号一样 private static final long serialVersionUID =456464445452L; public Teacher() { } public Teacher(int id, String name) { this.id = id; this.name = name; } @Override public String toString() { return "Teacher{" + "id=" + id + ", name='" + name + '\'' + '}'; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public static long getSerialVersionUID() { return serialVersionUID; } }
public class OtherStream { public static void main(String[] args) throws Exception { //标准的输入流: System.in 默认从键盘输入 //标准的输出流: System.out 默认从控制台输出 //setIn (InputStream)设置输入 setOut(PrintStream) 设置输出 // 键盘输入字符串->“整行”输出大写字符串 exit结束(@Test执行时会执行不了) //1.接收数据 用转换流的原因 字节流才能使用System.in 用完之后要转换成字符 System.out.println("请输入想要转换的字符串"); InputStreamReader isr = new InputStreamReader(System.in); //2.把数据放入缓冲流(因为缓冲流有接收一行的方法) BufferedReader br = new BufferedReader(isr); //3。操作数据 while (true){ String data= br.readLine(); //不区分大小写 if ("exit".equalsIgnoreCase(data)) { break; } //转为大写 String result = data.toUpperCase(); System.out.println(result); } //4.关闭流(记得try catch finally) br.close(); } @Test public void printStream() { //打印流 //PrintStream PrintWriter //特点 1.不会抛IOException 2.只能接受相对应的流 3.都有自动flush()功能 //4.打印的所有字符都是使用平台的默认字符转换编码转换为字节,在需要使用字符而不是字节的情况下用PrintWriter //1.实例化 注意不能用FileWrite printStream不能接收FileWrite的对象 PrintStream ps = null; try { FileOutputStream fos = new FileOutputStream("hi21.txt"); //2.创建打印流 true 是设置自动刷新(换行即刷新) ps = new PrintStream(fos,true); System.setOut(ps); for (int i = 50; i <255; i++) { //输出的是 System.out.print((char)i); //实现每读取5个数据进行换行 if (i % 50==0) { System.out.println(); } } } catch (FileNotFoundException e) { e.printStackTrace(); } finally { if (ps != null) { try { ps.close(); } catch (Exception e) { e.printStackTrace(); } } } }