02

    科技2022-07-31  101

    1 File类的使用

    1.1 File类的理解

    每一个File file = new File(“path”)都是文件系统中的一个文件或者文件目录

    File类声明在java.io包下

    File类中涉及了关于文件或文件目录的创建createNewFile();mkdir();mkdirs(),删除delete(),重命名renameTo(),修改时间lastModified(),文件大小length()等方法

    并没有涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容,必须使用IO流来完成。

    后续File类的对象常会作为参数传递到流的构造器中,指明读取或写入的“终点”。

    1.2 File的实例化

    常用构造器

    File file = new File(String filepath); File file = new File(String parentPath, String childPath); File file = new File(File parentFile, String childPath);

    路径的分类

    相对路径:相较于某个路径下,指明的路径。绝对路径:包含盘符在内的文件或文件目录的路径

    说明:

    IDEA中: 如果大家开发使用JUnit中的单元测试方法测试,相对路径即为当前Module下。 如果大家使用main()测试,相对路径即为当前的Project下。 Eclipse中: 不管使用单元测试方法还是使用main()测试,相对路径都是当前的Project下。

    路径分隔符

    windows和DOS系统默认使用“\”来表示 UNIX和URL使用“/”来表示

    1.3 File常用方法

    public class FileTest { @Test public void test1(){ //构造器1:File(String pathname) File file1 = new File("hello.txt"); File file2 = new File("F:\\workspace\\SGU_Java_course\\IO\\hello.txt"); System.out.println(file1); System.out.println(file2); //构造器2:File(String parentPath, String childPath) File file3 = new File("F:\\workspace\\SGU_Java_course", "IO"); System.out.println(file3); //构造器3:File(File parentFile, String childPath) File file4 = new File(file3, "HelloWorld"); } @Test public void test2(){ //注意此时file1的相对路径是在src目录下的,并不是在www.code...下的。 File file1 = new File("hello.txt"); File file2 = new File("F:\\workspace\\SGU_Java_course\\IO\\hi.txt"); //1. 获取绝对路径 System.out.println(file1.getAbsolutePath()); System.out.println(file2.getAbsolutePath()); //2. 获取路径(写的什么路径就是什么) System.out.println(file1.getPath()); System.out.println(file2.getPath()); //3. 获取名称(获取文件名) System.out.println(file1.getName()); System.out.println(file2.getName()); //4. 获取上层目录路径(写的相对路径的话,往上找找不到,写绝对路径就可以。) System.out.println(file1.getParent()); System.out.println(file2.getParentFile()); //5. 获取文件长度(字节数),不能获取目录的长度 System.out.println(file1.length()); //6. 获取最后一次修改的时间,毫秒值 long l = file1.lastModified(); Date date = new Date(l); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); String format = simpleDateFormat.format(date); System.out.println(format);//转换成现在的时间 } @Test public void test3(){ File file = new File("F:\\workspace\\SGU_Java_course"); //7. 获取指定目录下的所有文件或文件目录的名称数组(如果路径找不到就会报错) //以文件名的形式显示。 String[] list = file.list(); for (String s : list) { System.out.println(s); } System.out.println("************************************"); //8. 获取指定目录下的所有文件或文件目录的File数组 //以绝对路径的形式显示。 File[] files = file.listFiles(); for (File file1 : files) { System.out.println(file1); } } @Test public void test4(){ File file1 = new File("F:\\workspace\\SGU_Java_course\\file.txt"); File file2 = new File("F:\\workspace\\SGU_Java_course\\IO\\hello.txt"); //renameTo重命名文件(相同路径下),当不同路径renameTo就是剪切后重命名 boolean b = file1.renameTo(file2); System.out.println(b); } @Test public void test5(){ File file1 = new File("hello.txt"); File file2 = new File("hi.txt"); //判断文件是否存在 boolean exists1 = file1.exists(); System.out.println(exists1); boolean exists2 = file2.exists(); System.out.println(exists2); //判断是否是一个文件 boolean file = file1.isFile(); System.out.println(file); //判断是否是一个文件目录 boolean directory = file1.isDirectory(); System.out.println(directory); File file3 = new File("F:\\workspace\\SGU_Java_course\\IO"); boolean directory1 = file3.isDirectory(); System.out.println(directory1); //判断是否可读 boolean read = file1.canRead(); System.out.println(read); boolean b = file2.canRead(); System.out.println(b); boolean b1 = file3.canRead(); System.out.println(b1); //判断是否可写 boolean write = file1.canWrite(); System.out.println(write); //判断是否隐藏 boolean hidden = file1.isHidden(); System.out.println(hidden); } @Test public void test6() throws IOException { //文件的创建 File file1 = new File("F:\\workspace\\SGU_Java_course\\IO\\hadoop.txt"); if (!file1.exists()){ //file.createNewFile()创建新文件;返回为boolean boolean newFile = file1.createNewFile(); if (newFile){ System.out.println("创建成功"); }else { System.out.println("创建失败"); } }else { //file.delete()删除文件;返回为boolean boolean delete = file1.delete(); if (delete){ System.out.println("删除成功"); } } } @Test public void test7(){ //文件目录创建 File file = new File("F:\\workspace\\SGU_Java_course\\IO\\IO1"); if (!file.exists()){ //mkdir()创建文件目录 boolean mkdir = file.mkdir(); if (mkdir){ System.out.println("文件目录创建成功"); } }else { //文件目录删除也是用delete boolean delete = file.delete(); if (delete){ System.out.println("文件目录删除成功"); } } } @Test public void test8(){ //创建多级目录 File file = new File("F:\\workspace\\SGU_Java_course\\IO\\IO1\\IO21"); //可以看到创建多级目录mkdir就不行了 boolean mkdir = file.mkdir(); System.out.println(mkdir); //创建多级目录 if (!file.exists()){ boolean mkdirs = file.mkdirs(); if (mkdirs){ System.out.println("多级目录创建成功"); } }else { //多级目录的删除也是用delete //当待删除目录中存在文件就不能删除 boolean delete = file.delete(); if (delete){ System.out.println("多级目录删除成功"); } } } }

    1.4 File的应用实例

    递归显示某个文件夹中的所有内容

    public class Test1 { public static void main(String[] args) { File file = new File("./testFile"); listSubFile(file); } public static void listSubFile(File file){ //输入的文件检验 if (file.exists() && file.isDirectory()){ //首先获取输入的这个文件的数组 File[] files = file.listFiles(); //如果输入的文件夹不是空文件夹 if (files != null){ //获取每一个文件名 for (File file1 : files) { //打印所有的文件名称,包括文件夹的 System.out.println(file1.getName()); if (file1.isDirectory()) listSubFile(file1); // //只打印文件的名称 // if (file1.isFile()) // System.out.println(file1.getName()); // if (file1.isDirectory()) // listSubFile(file1); } } } } }

    递归删除某个文件夹中的所有内容

    public class Test2 { @Test public void test1(){ File file = new File("./testFile2"); delSubFile(file); } //递归删除方法 public void delSubFile(File file){ //首先判断传进来的文件目录是不是存在,并且判断是不是文件夹 if (file.exists() && file.isDirectory()){ //或得该目录下的所有一级内容 File[] files = file.listFiles(); for (File file1 : files) { if (file1.isDirectory()){ delSubFile(file1); } file1.delete(); } } } }

    递归删除某个文件夹中的空白文件夹

    public class Test3 { @Test public void test(){ File file = new File("./testFile2"); delEmptyDir(file); } public void delEmptyDir(File file){ if (file.exists() && file.isDirectory()){ File[] files = file.listFiles(); for (File file1 : files) { if (file1.isDirectory()){ File[] files1 = file1.listFiles(); //空白文件夹内的长度=0; if (files1.length == 0){ file1.delete(); //非空文件夹,递归删除里面的 }else { delEmptyDir(file1); } } } } } }

    2 IO流概述

    2.1 流的分类

    按照数据处理单位分类:字节流(InputStream\OutputStream)、字符流(Reader\Writer)按照数据的流向分类:输入流(InputStream\Reader)、输出流i(OutputStream\Writer)按照流的角色分类:节点流、处理流

    2.2 流的体系结构

    抽象基类:InputStream\OutputStream\Reader\Writer访问文件的流:FileInputStream\FileOutputStream\FileReader\FileWriter缓冲流:BufferedFileInputStream\BufferedFileOutputStream\BufferedReader\BufferedWriter

    2.3 重点说明的几个流节点

    抽象基类 节点流(文件流) 缓冲流(处理流的一种)

    InputStream FileInputStream BufferedInputStream

    OutputStream FileOutputStream BufferedOutputStream

    Reader FileReader BufferedReader

    Writer FileWriter BufferedWriter

    2.3 输入、输出的标准化过程

    输入过程

    创建File类的对象,指明读取的数据的来源(要求此文件一定存在)、

    创建相应的输入流,将File类的对象作为参数传入流的构造器

    具体的读入过程:

    ​ 创建相应的byte[] 或char[]

    关闭流资源

    说明:程序中出现的异常需要使用try-catch-finally处理

    输出过程

    创建File类的对象,指明写出的数据的位置(不要求此文件一定存在)

    创建相应的输出流,将File类的对象作为参数,传入流的构造器中

    具体的写入过程:

    write(char[]/byte[] buffer , 0, len)

    其中buffer是char类型或byte类型的数组,写出文件时是从0到len长度

    关闭流资源

    说明:程序中出现的异常需要使用try-catch-finally处理

    3 节点流(或文件流)

    3.1 FileReader、FileWriter的使用

    FileReader read()的理解:返回读入的一个字符。如果达到文件末尾,返回-1异常的处理:为了保证流资源一定可以执行关闭操作,需要使用try-catch-finally处理读入的文件一定要存在,不然会产生FileNotFoundException FileWriter 输出操作,对应的File文件可以不存在,并不会报异常File对应的硬盘文件如果存在: 如果流使用的构造器是:FileWriter(file, false)/FileWriter(file):对源文件的覆盖如果流使用的构造器是:FileWriter(file, true):对源文件的追加

    FileReader的使用

    读取某个文件的内容,写入到控制台中

    @Test public void testFileReader(){ FileReader fr = null; try { //1创建文件对象 File file = new File("hello.txt"); //2创建流对象,将文件作为参数传入到流的构造器中 fr = new FileReader(file); //3处理数据 //方式一:创建字符型的数组 char[] buffer = new char[5]; //定义每次读取char型数组中的元素个数 int len; //read(char[] buffer)返回的是buffer数组中字符的个数,如果达到末尾返回-1 while ((len = fr.read(buffer)) != -1){ //方式1:使用String(char[] buffer, 0, len)构造器,使用String接收 String str = new String(buffer, 0, len); System.out.print(str); //方式2:使用for循环遍历char[] //for(int i = 0; i < len; i++){ //System.out.print(buffer[i]); //} } //方式二 //int data = fr.read(); // while(data != -1){ // System.out.print((char)data); //data = fr.read(); //} } catch (IOException e) { e.printStackTrace(); } finally { //4关闭流资源 if (fr != null) { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } }

    FileWriter的使用

    读取某个文件内容,输出到另一个文件中。

    FileWriter(String descPath, true)//true,表示追加到目标文件内,默认为false,如果没有目标文件则创建,如果存在目标文件则覆盖。

    @Test public void testFileWriter() { FileReader fr = null; FileWriter fw = null; try { //造文件 File srcFile = new File("hello.txt"); File descFile = new File("descFile.txt"); //造流 fr = new FileReader(srcFile); fw = new FileWriter(descFile, true);//使用true表示追加在目标文件后 //处理数据 char[] buffer = new char[5]; int len; while ((len = fr.read(buffer)) != -1){ fw.write(buffer, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { if (fr != null){ //关闭流资源 try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } if (fw != null){ try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } } }

    3.2 FileInputStream、FileOutputStream的使用

    对于文本文件(.txt;.java;.c;.cpp),使用字符流处理对于非文本文件(.jpg;.mp4;.doc;.ppt)等,使用字节流处理

    FileInputStream

    构造器: FileinputStream(File file)FileInputStream(String filePath)

    方法:

    FileOutStream

    构造器: FileOutPutStream(File file)FileOutPutStream(String filePath)FileOutPutStream(File file, boolean append)FileOutPutStream(String filePath, boolean append)

    方法:

    FileInputStream的使用

    //第一种方式:单个字节的读取 FileInputStream fis = new FileInputStream("./testIO/a.txt"); int data = fis.read(); whihe(data != -1){ System.out.print((char)data); data = fis.read(); } fis.close(); //第二种方式:字节数组的方式读取 FileInputStream fis = new FileInputStream("./testIO/a.txt"); byet[] buffer = new byte[5]; int len; while((len = fis.read(buffer)) != -1){ String str = new String(buffer, 0, len); System.out.print(str); } fis.close();

    FileOutputStream的使用

    实现对图片的复制

    @Test public void testFileInputStream(){ FileInputStream fis = null; FileOutputStream fos = null; try { //造文件 File srcFile = new File("picture.png"); File descFile = new File("descPicture.png"); //造流 fis = new FileInputStream(srcFile); fos = new FileOutputStream(descFile); //处理数据,使用byte[] byte[] buffer = new byte[5]; int len; //复制图片 while ((len = fis.read(buffer)) != -1){ fos.write(buffer, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null){ //关闭流资源 try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } if (fos != null){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } }

    4 缓冲流

    4.1 缓冲流涉及到的类

    BufferedReaderBufferedWriterBufferedInputStreamBufferedOutputStream

    4.2 缓冲流作用

    作用:提高流的读取速度、写入速度提高读写速度的原因:内部提供了一个缓冲区,默认情况下是8kb

    4.3 flush和close

    IO流中每一个类都实现了Closeable接口,它们进行资源操作之后都需要执行close()方法将流关闭 。但字节流与字符流的不同之处在于:字节流是直接与数据产生交互,而字符流在与数据交互之前要经过一个缓冲区 。

    使用字符流对资源进行操作的时候,如果不使用close()方法,则读取的数据将保存在缓冲区中

    @Test public void test2() throws IOException { FileWriter fos = new FileWriter("iotest\\file2.txt"); fos.write("尚硅谷"); fos.flush(); fos.write("hello");//写出文件内容:尚硅谷 } @Test public void test3() throws IOException { FileOutputStream fos = new FileOutputStream("iotest\\file3.txt"); fos.write("hello".getBytes()); fos.flush(); fos.write("hi".getBytes());//写出文件内容:hello }

    BufferedReader、BufferedWriterc复制文本文件

    @Test public void testBufferedReader(){ //造文件 BufferedReader br = null; BufferedWriter bw = null; try { File srcFile = new File("hello.txt"); File descFile = new File("descHello.txt"); //造流 FileReader fr = new FileReader(srcFile); FileWriter fw = new FileWriter(descFile, true); //包一层处理流 br = new BufferedReader(fr); bw = new BufferedWriter(fw); //处理数据 char[] cBuf = new char[5]; int len; while ((len = br.read(cBuf)) != -1){ // String str = new String(cBuf, 0, len); // System.out.print(str); bw.write(cBuf, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { if (br != null){ //关闭资源 try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (bw != null){ try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } } }

    BufferedInputStream、BufferedOutputStream复制字节文件

    @Test public void testBufferedInputStream() { BufferedInputStream bis = null; BufferedOutputStream bos = null; try { //造文件 File srcFile = new File("picture.png"); File descFile = new File("pictureInputStream.jpg"); //造节点流 FileInputStream fis = new FileInputStream(srcFile); FileOutputStream fos = new FileOutputStream(descFile); //造缓冲流 bis = new BufferedInputStream(fis); bos = new BufferedOutputStream(fos); //处理数据 byte[] buffer = new byte[5]; int len; while ((len = bis.read(buffer)) != -1){ bos.write(buffer, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { if (bis != null){ //关闭流资源 try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } if (bos != null){ try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } } }

    5 转换流

    5.1 转换流涉及到的类(属于字符流)

    InputStreamReader:将一个字节的输入流转换为字符的输入流 解码:字节、字节数组 —> 字符数组、字符串 OutputStreamWriter:将一个字符的输出流转换成字节的输出流 解码:字符数组、字符串 —> 字节、字节数组

    5.2 作用

    提供了字节流和字符流之间的转换

    5.3 字符集

    ASCII:美国标准信息交换码 用一个字节的7位可以表示 ISO8859-1:拉丁码表。欧洲码表 用一个字节的8位表示。 GB2312:中国的中文编码表。最多两个字节编码所有字符GBK:中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码Unicode:国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的字符码。所有的文字都用两个字节来表示。UTF-8:变长的编码方式,可用1-4个字节来表示一个字符。

    InputStreamReader的使用

    //转换流,读取一个UTF-8编码的文件,解码显示在控制台 @Test public void test1() { InputStreamReader isr = null; try { //1.造文件,造流,造处理流 FileInputStream fis = new FileInputStream(new File("dbcp.txt")); //解码 isr = new InputStreamReader(fis,"utf-8"); //2.处理数据 char[] cbuf = new char[20]; int len; while ((len = isr.read(cbuf)) != -1){ String str = new String(cbuf, 0, len); System.out.print(str); } } catch (IOException e) { e.printStackTrace(); } finally { if (isr != null){ //3.关闭资源 try { isr.close(); } catch (IOException e) { e.printStackTrace(); } } } }

    InputStreamReader、OutputStreamWriter的综合使用

    //综合使用InputStreamReader、OutputStreamWriter @Test public void test2(){ InputStreamReader isr = null;//指定编码格式 OutputStreamWriter osw = null;//指定解码格式 try { //1. 造文件,造流,造处理流 FileInputStream fis = new FileInputStream("dbcp.txt"); FileOutputStream fos = new FileOutputStream("dbcp2.txt"); isr = new InputStreamReader(fis, "utf-8"); osw = new OutputStreamWriter(fos, "utf-8"); //2. 处理数据 char[] cbuf = new char[20]; int len; while ((len = isr.read(cbuf)) != -1){ osw.write(cbuf, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { if (isr != null){ //3. 关闭资源 try { isr.close(); } catch (IOException e) { e.printStackTrace(); } } if (osw != null){ try { osw.close(); } catch (IOException e) { e.printStackTrace(); } } } }

    6 其他流的使用

    6.1 标准输入输出流

    System.in:标准输入流,默认从键盘输入System.out:标准输出流,默认控制台输出 修改默认的输入:System.setIn(InputStream is)修改默认的输出:System.setOut(PrintStream ps)

    练习题

    从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续进行输入操作, 直至当输入“e”或者“exit”时,退出程序。

    方式一:使用while循环+Scanner方式二:利用缓冲流中的readLine()方法 首先创建一个InputStreamReader输入转换流使用其InputStreamReader(InputStream)的构造器,因为是从控制台输入,所以构造器内的输入流为System.in然后将转换流作为BufferedInputStream()的参数传入,然后调用BufferedInputStream的readLine()方法,读取字符串 public class Test04 { //方式一:使用Scanner(System.in)的方式 // public static void main(String[] args) { // while (true) { // Scanner scanner = new Scanner(System.in); // System.out.println("请输入字符串:"); // String line = scanner.nextLine(); // if (line.equals("e") || line.equals("exit")) { // break; // } // String up = line.toUpperCase(); // System.out.println(up); // } // // } //方式二:使用System.in实现,System.in ---> 转换流 ---> BufferedReader的readLine() public static void main(String[] args) { BufferedReader br = null; try { //转换流InputStreamReader(输入流) InputStreamReader isr = new InputStreamReader(System.in); //BufferedReader处理流 br = new BufferedReader(isr); while (true){ System.out.println("请输入字符串"); String data = br.readLine(); if (data.equalsIgnoreCase("e") || data.equalsIgnoreCase("exit")){ break; } String string = data.toUpperCase(); System.out.println(string); } } catch (IOException e) { e.printStackTrace(); } finally { if (br != null){ try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } } }

    6.2 打印流

    PrintStreamPrintWriter

    练习题

    打印0-255的ASCII码,输出到本地文件中

    @Test public void test2() { PrintStream ps = null; try { FileOutputStream fos = new FileOutputStream(new File("D:\\IO\\text.txt")); // 创建打印输出流,设置为自动刷新模式(写入换行符或字节 '\n' 时都会刷新输出缓冲区) ps = new PrintStream(fos, true); if (ps != null) {// 把标准输出流(控制台输出)改成文件 System.setOut(ps); } for (int i = 0; i <= 255; i++) { // 输出ASCII字符 System.out.print((char) i); if (i % 50 == 0) { // 每50个数据一行 System.out.println(); // 换行 } } } catch (FileNotFoundException e) { e.printStackTrace(); } finally { if (ps != null) { ps.close(); } } }

    6.3 数据流

    DataInputStreamDataOutputStream

    作用:用于读取或写出基本数据类型的变量或字符串,从内存写出到磁盘,从磁盘写入到内存

    练习题

    练习:将内存中的字符串、基本数据类型的变量写出到文件中。

    此时是乱码的~

    @Test public void test1(){ DataOutputStream dos = null; try { //1 造流;将内存中的数据存入到磁盘,应该是输出流 dos = new DataOutputStream(new FileOutputStream("out1.txt")); //2 处理数据 dos.writeUTF("Tom");//写入字符串 dos.writeInt(23);//写入整型 dos.writeBoolean(true);//写入布尔型 } catch (IOException e) { e.printStackTrace(); } finally { if (dos != null){ //3 关闭资源 try { dos.close(); } catch (IOException e) { e.printStackTrace(); } } } }

    将本地文件的内容重写写入到内存

    @Test public void test2(){ DataInputStream dis = null; try { //1 造文件,造流;此时相对于内存来说是写入数据 dis = new DataInputStream(new FileInputStream("data.txt")); //2 将数据写入到内存 //注意的是此时的写入内存的顺序必须和当时写入到磁盘的顺序一样 String name = dis.readUTF(); int age = dis.readInt(); boolean gender = dis.readBoolean(); System.out.println("name:"+name); System.out.println("age:"+age); System.out.println("gender:"+gender); } catch (IOException e) { e.printStackTrace(); } finally { if (dis != null){ //3 关闭资源 try { dis.close(); } catch (IOException e) { e.printStackTrace(); } } } }

    7 对象流

    ObjectOutputStream:内存中的对象 —> 存储的文件、通过网络传输出去到另一个节点,序列化过程ObjectInputStream:存储中的文件、通过网络接收过来 —> 内存的对象。反序列化过程

    7.1 对象的序列化机制

    对象的序列化机制: 序列化过程:允许把内存的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久化保存到磁盘上,或者通过网络将这种二进制流传送到另一个网络节点。反序列化过程:当其他程序获得了这种二进制和流,就可以恢复成原来的Java对象

    7.2 序列化的代码实现

    package www.codejiwei.java; import org.junit.Test; import java.io.*; /** * @Author jiweicode * @Date 2020/9/10 - 10:59 * @Version 1.0 * @Description * 对象流: * ObjectOutputStream ObjectInputStream * 1. 作用:用于存储基本数据类型数据或对象的处理流,可以把Java对象写入到数据源中,也可以把对象从数据源中还原回来 * 2. 要想一个Java对象是可序列化的,需要满足: * 2.1 类要实现Serializable接口(标识接口) * 2.2 当前类需要具有一个全局常量,序列化常量SerialVersionUID * 2.3 除了当前类实现Serializable接口之外,还必须保证其内部的所有属性也是可序列化的(默认基本数据类型都是可序列化的) * 补充:ObjectOutputStream和ObjectInputStream不能序列化static和t'ransient修饰的属性 * 3.序列化机制: * 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种 * 二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。 * 当其它程序获取了这种二进制流,就可以恢复成原来的Java对象。 **/ //String的序列化到本地文件object.dat public class ObjectInputOutputStreamTest { @Test public void testObjectOutputStream(){ ObjectOutputStream oos = null; try { //1. oos = new ObjectOutputStream(new FileOutputStream("object.dat")); //2. oos.writeObject(new String("我爱北京天安门")); oos.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (oos != null){ //3. try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } } } //String对象的反序列化,读取本地文件转换为String对象 @Test public void testObjectInputStream(){ ObjectInputStream ois = null; try { //1. ois = new ObjectInputStream(new FileInputStream("object.dat")); //2. Object o1 = ois.readObject(); String str = (String)o1; System.out.println(str); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { if (ois != null) { //3. try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } } } //将Person对象序列化存为本地文件 @Test public void testObjectOutputStream2(){ ObjectOutputStream oos = null; try { //1. oos = new ObjectOutputStream(new FileOutputStream("object.dat")); //2. oos.writeObject(new Person("Tom", 23, new Account(1))); oos.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (oos != null) { //3. try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } } } //Person对象的反序列化,读取本地文件转换为Person对象 @Test public void testObjectInputStream2(){ ObjectInputStream ois = null; try { //1 ois = new ObjectInputStream(new FileInputStream("object.dat")); //2 Object object = ois.readObject(); Person p1 = (Person)object; System.out.println(p1); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { if (ois != null) { //3 try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } } } } package www.codejiwei.java; import java.io.Serializable; /** * @Author jiweicode * @Date 2020/9/10 - 11:56 * @Version 1.0 * @Description **/ //Person对象必须实现Serializable接口;提供SerialVersionUID序列号;Account对象作为属性出现也必须实现Serializable接口 public class Person implements Serializable { private String name; private int age; private Account account; private static final long serialVersionUID = -694470754667710L; public Person(String name, int age) { this.name = name; this.age = age; } public Person(String name, int age, Account account) { this.name = name; this.age = age; this.account = account; } public Person() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public static long getSerialVersionUID() { return serialVersionUID; } public Account getAccount() { return account; } public void setAccount(Account account) { this.account = account; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + ", account=" + account + '}'; } } class Account implements Serializable{ private int id; public Account(int id) { this.id = id; } public Account() { } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public String toString() { return "Account{" + "id=" + id + '}'; } }

    8 随机读取文件流

    8.1 RandomAccessFile类

    RandomAccessFile类直接继承于java.lang.Object类,实现了DataInput和DataOutput接口RandomAccessFile既可以作为y一个输入流,也可以作为一个输出流如果RandomAccessFile作为输出流时,写出的文件如果不存在,则在执行过程中自动创建; 如果写出的文件存在,则会覆盖源文件内容(默认从文件头覆盖) 可以通过相关的操作,实现RandomAccessFile的插入。方法:seek(int num)定位到num位置

    8.2 典型代码

    使用RandomAccessFile复制图片

    @Test public void test1(){ RandomAccessFile raf1 = null; RandomAccessFile raf2 = null; try { //1. 造文件造流 //1.1 从本地文件读取 raf1 = new RandomAccessFile(new File("beauty.jpg"),"r"); //1.2 写入到本地的哪里? raf2 = new RandomAccessFile("beauty1.jpg", "rw"); //2. 处理数据,将图片资源使用字节数组进行存储 byte[] buffer = new byte[1024]; int len; while ((len = raf1.read(buffer)) != -1){ raf2.write(buffer, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { //3. 关闭资源 if (raf1 != null){ try { raf1.close(); } catch (IOException e) { e.printStackTrace(); } } if (raf2 != null){ try { raf2.close(); } catch (IOException e) { e.printStackTrace(); } } } }

    使用RandomAccessFile实现文本中插入操作

    在文件hello.txt中的abcdefghijklmn的c后面插入zxf

    @Test public void test2(){ RandomAccessFile raf1 = null; try { //1. 造文件造流 raf1 = new RandomAccessFile(new File("hello.txt"), "rw"); //2. 处理数据 //2.1 首先将指针指到3的位置,复制后面的所有数据 raf1.seek(3); StringBuilder sbf = new StringBuilder((int) new File("hello.txt").length()); byte[] buffer = new byte[20]; int len; while ((len = raf1.read(buffer)) != -1){ sbf.append(new String(buffer, 0, len)); } //2.2 调回指针,添加要插入的数据 raf1.seek(3); raf1.write("zxf".getBytes()); //2.3 将StringBuilder的数据写入文件 raf1.write(sbf.toString().getBytes()); } catch (IOException e) { e.printStackTrace(); } finally { if (raf1 != null){ //3. 关闭资源 try { raf1.close(); } catch (IOException e) { e.printStackTrace(); } } } }

    9 Path、Paths、Files的使用

    1.NIO的使用说明:

    Java NIO (New IO,Non-Blocking IO)是从Java 1.4版本开始引入的一套新的IO API,可以替代标准的Java IO AP。 NIO与原来的IO同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的(IO是面向流的)、基于 通道的IO操作。 NIO将以更加高效的方式进行文件的读写操作。 随着 JDK 7 的发布,Java对NIO进行了极大的扩展,增强了对文件处理和文件系统特性的支持,以至于我们称他们为 NIO.2。

    2.Path的使用 —jdk7提供 2.1Path的说明: Path替换原有的File类。 2.2如何实例化:

    2.3常用方法:

    3.Files工具类 —jdk7提供 3.1作用: 操作文件或文件目录的工具类 3.2常用方法:

    Processed: 0.012, SQL: 8