Java程序设计(高级及专题)- IO流与序列化

Java程序设计(高级及专题)- IO流与序列化

在这里插入图片描述

  • 今天我们讲讲I/O流与序列化的问题?
    个人理解:在我们在编程开发的时候,往往会涉及到文件的读取与写入,而java为我们提供的I/O流就是用来解决这个问题的。我们在读取和写入文件的时候,都会涉及到序列化的东西,谈到序列化就离不开编码格式,我们的windows是用GBK来编码的而我们的Java通常是用UTF-8来编码的,所以我们有时候开发会遇到乱码的问题,此时我们不要慌,问题总是会能解决的,大不了从新来吗;哪么我们回过头来看看I/O,它有五类一接口一关键字,分别是InputStream字节输入流(文件写入)、OutputStream字节输出流(文件读取)、Reader字符输入流(文件写入)、Writer字符输出流(文件读取)、File文件类(文件路径)和Serializable标识接口(序列化的标准)以及transient(反序列化关键字);一个字符等于两个字节,字符流能处理的字节流都能处理,字符流不一定能够处理字节流的事物。

File类

/* File读取文件的三种方式(第三种常用) File.separator 可以看成 // 从盘符开始写,是绝对路径 如:e:\\work\\workspace\\ioDemo\\txt\\aaa.txt 直接写是相对路径,相对工程下的.classpath文件 f1.createNewFile();只能新建一个文件,不能新建文件夹 file.list();//该方法只能得到该目录下子目录的文件名的String集合 */
       File f=new File("D:"+File.separator+"aaa"+File.separator+"aaa.txt");
		/* File f1=new File("D:"+File.separator+"aaa","aaa.txt"); File parent=new File("D:"+File.separator+"aaa"); File child=new File(parent,"aaa.txt");*/

下面是它的一些方法:

序号 方法 介绍
1 public String getName() 返回由此抽象路径名表示的文件或目录的名称。
2 public String getParent() 返回此抽象路径名的父路径名的路径名字符串,如果此路径名没有指定父目录,则返回 null。
3 public File getParentFile() 返回此抽象路径名的父路径名的抽象路径名,如果此路径名没有指定父目录,则返回 null。
4 public String getPath() 将此抽象路径名转换为一个路径名字符串。
5 public boolean isAbsolute() 测试此抽象路径名是否为绝对路径名。
6 public String getAbsolutePath() 返回抽象路径名的绝对路径名字符串。
7 public boolean canRead() 测试应用程序是否可以读取此抽象路径名表示的文件。
8 public boolean canWrite() 测试应用程序是否可以修改此抽象路径名表示的文件。
9 public boolean exists() 测试此抽象路径名表示的文件或目录是否存在。
10 public boolean isDirectory() 测试此抽象路径名表示的文件是否是一个目录。
11 public boolean isFile() 测试此抽象路径名表示的文件是否是一个标准文件。
12 public long lastModified() 返回此抽象路径名表示的文件最后一次被修改的时间。
13 public long length() 返回由此抽象路径名表示的文件的长度。
14 public boolean createNewFile() throws IOException 当且仅当不存在具有此抽象路径名指定的名称的文件时,原子地创建由此抽象路径名指定的一个新的空文件。
15 public boolean delete() 删除此抽象路径名表示的文件或目录。
16 public void deleteOnExit() 在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。
17 public String[] list() 返回由此抽象路径名所表示的目录中的文件和目录的名称所组成字符串数组。
18 public String[] list(FilenameFilter filter) 返回由包含在目录中的文件和目录的名称所组成的字符串数组,这一目录是通过满足指定过滤器的抽象路径名来表示的。
19 public File[] listFiles() 返回一个抽象路径名数组,这些路径名表示此抽象路径名所表示目录中的文件。
20 public File[] listFiles(FileFilter filter) 返回表示此抽象路径名所表示目录中的文件和目录的抽象路径名数组,这些路径名满足特定过滤器。
21 public boolean mkdir() 创建此抽象路径名指定的目录。
22 public boolean mkdirs() 创建此抽象路径名指定的目录,包括创建必需但不存在的父目录。
23 public boolean renameTo(File dest) 重新命名此抽象路径名表示的文件。
24 public boolean setLastModified(long time) 设置由此抽象路径名所指定的文件或目录的最后一次修改时间。
25 public boolean setReadOnly() 标记此抽象路径名指定的文件或目录,以便只可对其进行读操作。
26 public static File createTempFile(String prefix, String suffix, File directory) throws IOException 在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。
27 public static File createTempFile(String prefix, String suffix) throws IOException 在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。
28 public int compareTo(File pathname) 按字母顺序比较两个抽象路径名。
29 public int compareTo(Object o) 按字母顺序比较抽象路径名与给定对象。
30 public boolean equals(Object obj) 测试此抽象路径名与给定对象是否相等。
31 public String toString() 返回此抽象路径名的路径名字符串。

InputStream 字节输入流

package com.gaoji.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
//输入字节流
public class IOdome_03 {
   
    //读取字节流InputStream
    public static void main(String[] args) throws IOException   {
   
        File f1 = new File("D://");//目标文件夹
        File f2 = new File(f1, "aaa.txt");//目标文件
        
        InputStream in =null;
        try {
   
            in = new FileInputStream(f2);//对该流进行实例化赋值
            int a = 0;//用于介绍流中独处的内容
// in.skip(1);//跳过n个字节不读
// 第一种方法
// while ((a=in.read())!=-1) {
   
// System.out.print((char)a);
// }
// 第二种方法(比较耗内存,速度会变快)
            byte[] bs = new byte[in.available()];
            while ((a=in.read())!=-1) {
   
                for(int i=0;i<bs.length;i++){
   
                    if(bs[i]==0){
   
                        break;
                    }
                }
                System.out.print((char)a);
            }
        } catch (Exception e) {
   
            e.printStackTrace();
        } finally{
   
            in.close();
        }
    }
}

OutputStream 字节输出流

package com.gaoji.io;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
//输出字节流
public class IOdome_04 {
   
    //写入字节流OutputStream
    public static void main(String[] args) throws IOException {
   
        File f1 = new File("D://");//目标文件夹
        File f2 = new File(f1, "aaa.txt");//目标文件
        OutputStream out=null;
        try {
   
            out=new FileOutputStream(f2,true);//true是续写,false是重写
            String a="holle wrold1";
// 一个字节一个字节的写
// byte[] bs=a.getBytes();
// for (int i = 0; i < bs.length; i++) {
   
// out.write(bs[i]);
// }
// 一个数组的写
            out.write(a.getBytes());
        } catch (Exception e) {
   
            // TODO: handle exception
        }finally {
   
            out.flush();//刷新(字节流是自动刷新的,不过不写不规范)
            out.close();//关闭
        } 
    }
}

Reader 字符输入流

//读
    public static void reader() {
   
        try {
   
            InputStreamReader fr=new InputStreamReader(new FileInputStream(new File("D:\\aaa.txt")),"utf-8");
            char[] cs=new char[6];
            fr.read(cs);
            System.out.println(new String(cs));
            System.out.println(fr.getEncoding());
            fr.close();
    } catch (Exception e) {
   
            // TODO Auto-generated catch block
            e.printStackTrace();
    }
        
    }

Writer 字符输出流

在使用字节输出流可以不刷新文件流,系统会自动刷新,而字符输出流不一样,如果不刷新再关闭的话,文件不会有任何操作的。

//写
    public static void writer() {
   
        OutputStreamWriter ows = null;
        try {
   
            ows = new OutputStreamWriter(new FileOutputStream(new File("D://aaa.txt")), "gbk");
            String a = "今天天气不错";
            ows.write(a);
            System.out.println(ows.getEncoding());
        } catch (IOException e) {
   
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
   
            try {
   
                ows.flush();
                ows.close();
            } catch (IOException e) {
   
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

序列化与反序列化

  • User.java User实体类
package com.gaoji.io;

import java.io.Serializable;
//IO流里面的接口 Serializable
public class User implements Serializable {
   

    /** * 序列化编译id * transient //被他修饰的字段不会被序列化 */
    private static final long serialVersionUID = 4950216177746797393L;
    private int id;
    private String name;
    private char sex;
    private transient String phone;
    public User(int id, String name, char sex, String phone) {
   
        super();
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.phone = phone;
    }
    public User() {
   
        super();
    }
    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 char getSex() {
   
        return sex;
    }
    public void setSex(char sex) {
   
        this.sex = sex;
    }
    public String getPhone() {
   
        return phone;
    }
    public void setPhone(String phone) {
   
        this.phone = phone;
    }
    @Override
    public String toString() {
   
        return "User [id=" + id + ", name=" + name + ", sex=" + sex + ", phone=" + phone + "]";
    }
}

  • Run.java 序列化运行类
package com.gaoji.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
//对象的序列化与反序列化
public class IOdome_07 {

public static void main(String[] args) throws IOException, ClassNotFoundException {

xlh();
fxlh();
}
//对象序列化
public static void xlh() throws FileNotFoundException, IOException {

User u = new User(1, "张三", '男', "15665620000");
ObjectOutputStream out = null;
try {

out = new ObjectOutputStream(new FileOutputStream(new File("d:\\user.dat")));
out.writeObject(u);
System.out.println(u);
} finally {

out.flush();//刷新
out.close();//关闭
}
}
//对象反序列化
public static void fxlh() throws IOException, ClassNotFoundException {

ObjectInputStream in = null;
try {

in = new ObjectInputStream(new FileInputStream(new File("d:\\user.dat")));
User u = (User) in.readObject();
System.out.println(u.toString());
} finally {

in.close();
}
}
}

文件流实现复制

  • 字节流实现
//字节流 FileInputStream和FileOutputStream实现
public static void InputOutputStream() throws IOException {

File f1 = new File("D://");
File f2 = new File(f1, "qqq.jpg");
File f3 = new File("C://");
File f4 = new File(f3, "qqq.jpg");
FileInputStream fis = new FileInputStream(f2);//输入类(读取)
FileOutputStream fos = new FileOutputStream(f4);//输出类(写入)
int len = 0;
while ((len = fis.read()) != -1) {

fos.write(len);
}
fos.flush();
fos.close();
fis.close();
}
  • 字符流实现
//缓存字节流 BufferedInputStream和BufferedOutputStream实现
public static void BufferedInputOutputStream() throws IOException {

// TODO Auto-generated method stub
File f1 = new File("D://");
File f2 = new File(f1, "qqq.jpg");
File f3 = new File("C://");
File f4 = new File(f3, "qqq.jpg");
BufferedInputStream bin = null;
BufferedOutputStream out = null;
try {

byte[] bs = new byte[1024];
bin = new BufferedInputStream(new FileInputStream(f2));
out = new BufferedOutputStream(new FileOutputStream(f4));
while (bin.read(bs) != -1) {

out.write(bs);
}
} catch (Exception e) {

// TODO: handle exception
} finally {

bin.close();
out.flush();
out.close();
}
}

IO流用递归实现查找系统盘里面的所有文件

package com.gaoji.io;
import java.io.File;
public class IOdomemy_01 {

public static void main(String[] args) {

//File f = new File("D://");
File f = new File("D:\\");
//getFile(f);
}
//用递归实现查找系统盘里面的所有文件
public static void getFile(File f) {

File[] fs = f.listFiles();
if(fs != null && fs.length !=0){

for(File f1:fs){

if(f1.isDirectory()){

getFile(f1);
}else{

System.out.println(f1.getName());
}
}
}
}
}

试题巩固

1.在d盘根目录新建一个a.txt的文件,在文件中输入任意内容

package com.gaoji.io;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
//1.在d盘根目录新建一个a.txt的文件,在文件中输入任意内容
public class IOword_01 {

public static void main(String[] args) {

dome0111();
}
//用createTempFile创建文件
public static void dome01(){

File parent=new File("d:"+File.separator); 
try {

File file = parent.createTempFile("hjbqq",".txt",parent);
System.out.println(file);
//d:\hjbqq1465893390880583617.txt
} catch (IOException e) {

// TODO Auto-generated catch block
e.printStackTrace();
}
}
用createNewFile创建文件
public static void dome011(){

File f1=new File("d:"+File.separator);
File f2=new File(f1,"txt.txt");
try {

//有txt.txt则不创建,否,则相反
f2.createNewFile();
System.out.println("是否存在:"+f2.exists());
System.out.println(f2);
//d:\txt.txt
} catch (IOException e) {

// TODO Auto-generated catch block
e.printStackTrace();
}
}
//写入字符流
public static void dome0111(){

File f1=new File("d:"+File.separator);
File f2=new File(f1,"txt.txt");
try {

FileWriter fw = new FileWriter(f2);
BufferedWriter bw = new BufferedWriter(fw);
bw.write("啊啊啊啊");
bw.flush();//清除缓冲区
bw.close();
fw.close();
System.out.println("写入完毕");
} catch (IOException e) {

// TODO Auto-generated catch block
e.printStackTrace();
} 
}
}

2.读取txt.txt文件大小,最近访问时间,是否是一个目录。并删除此文件

package com.gaoji.io;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
//读取txt.txt文件大小,最近访问时间,是否是一个目录。并删除此文件
public class IOword_02 {

public static void main(String[] args) {

dome1();
}
public static void dome1() {

File f1 = new File("D:"+File.separator);
File f2 = new File(f1,"txt.txt");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
System.out.println(f2);
System.out.println(f2+"的文件大小是"+f2.length());
System.out.println(f2+"最后一次被修改的时间是"+sdf.format(new Date(f2.lastModified())));
System.out.println(f2+"是否是一个目录:"+f2.isDirectory());
if(f2.delete()){

System.out.println("删除成功!!");
}else{

System.out.println("删除失败");
}
}
}

3.编写一个程序,删除这个文件夹中的所有文件(用递归算法来实现)

package com.gaoji.io;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class IOword_03 {

//创建一个多层的文件夹,每个文件中有不同数目的文件,
//编写一个程序,删除这个文件夹中的所有文件(用递归算法来实现)
public static void main(String[] args) throws IOException {

File f1=new File("d:"+File.separator);
File f2 = new File(f1,"txt");
getFile(f2);
}
//删除指定目录下的文件
public static void getFile(File f) {

File[] fs = f.listFiles();
if(fs != null && fs.length !=0){

for(File f1:fs){

if(f1.isDirectory()){

getFile(f1);
}else{

f1.delete();
}
}
}
}
}

资源下载

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/106732.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • mysql报错注入_mysql报错注入[通俗易懂]

    mysql报错注入_mysql报错注入[通俗易懂]报错注入这里主要介绍3种MySQL数据库报错注入的发法,分别是updatexml、floor和exp。1.updatexmlupdatexml的报错原理从本质上来说就是函数的报错。selectupdatexml(1,concat(0x7e,(selectversion()),0x7e),1);这里还是使用前面的例子,举出一个爆破数据库版本的样例Payload:爆破数据库版本信息?id=1’+…

  • shell数组变量赋值_形参可以是常量变量或表达式

    shell数组变量赋值_形参可以是常量变量或表达式1.定义数组bash支持一维数组(不支持多维数组),并且没有限定数组的大小。类似于C语言,数组元素的下标由0开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于0。在Shell中,用括号来表示数组,数组元素用”空格”符号分割开。定义数组的一般形式为:【示例】定义数组:array_name=(value0value1value2value3)数组的值类型任意,个数不限可以不使用连续的下标,而且下标的范围没有限制:array_name=([0]

    2022年10月30日
  • 三极管驱动继电器电路

    三极管驱动继电器电路    继电器线圈需要流过较大的电流(约50mA)才能使继电器吸合,一般的集成电路不能提供这样大的电流,因此必须进行扩流,即驱动。图1所示为用NPN型三极管驱动继电器的电路图,图中阴影部分为继电器电路,继电器线圈作为集电极负载而接到集电极和正电源之间。当输入为0V时,三极管截止,继电器线圈无电流流过,则继电器释放(OFF);相反,当输入为+VCC时,三极管饱和,继电器线圈有相当的电流流过,…

  • 那些年我在CSDN追过的安全白帽师傅,respect「建议收藏」

    那些年我在CSDN追过的安全白帽师傅,respect「建议收藏」2019年7月,我来到了一个陌生的专业——网络空间安全专业。作为一个长期以Python数据挖掘和NLP方向为主的学生,突然换大方向,去从事系统安全和逆向分析的研究,还是挺难的,这两年的过程也极其艰辛。依稀记得,换专业当天我下定决心:希望利用未来四年时间,深入学习安全技术,学会撰写高质量论文,并通过分享让更多的初学者了解和入门安全领域。更期盼博士早日毕业,回到家乡贵州继续从事安全技术和大数据分析的教学。

  • UVA 11080 – Place the Guards(二分图判定)

    UVA 11080 – Place the Guards(二分图判定)

  • tkMapper插件的详细讲解[通俗易懂]

    tkMapper插件的详细讲解[通俗易懂]tkMapper插件的详细讲解一、tkMapper简介tkMapper就是一个MyBatis插件,是在MyBatis的基础上提供的开发工具,可以让开发变得简单,提高开发效率。作用:1、提供了针对单表通用的数据库操作方法2、逆向工程(根据数据表生成实体类、dao接口、映射文件)二、tkMapper整合1、基于SpringBoot完成MyBatis的整合2、整合tkMapper2.1、添加tkMapper的依赖2.2、修改启动类的@MapperScan注解的包为***tk.mybatis.spring.anno

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号