入门JAVA第十二天 IO流

一、IO输入输出流

1.1 流是什么

流是通道

在Java中流是提供数据传输的通道。

A==================>B

1.2 流的分类

按不同的方式将流进行不同的分类:

(1) 按方向:参照物是内存

        输入流和输出流

        编写一个程序,需要读文件中的内存到程序中来。需要使用输入流

        写文件需要将程序中的内存写到文件中,需要使用输出流

 (2) 按流量(传输大小)

        字节流字符流

        1个字符等于2个字节。

        一般字符流都是用来操作文本数据(文本文件)

        一般字节流都是用来操作二进制数据(声音,图片,视频)

最终我们可以得到流应用中的4个父类字节输入,字节输出,字符输入,字符输出。

(3) 扩展分类:按功能分类:

        节点流和过滤流

        节点流是直接操作源对象的流对象。源对象(A和B这两个点)

        过滤流是操作流对象的流对象。为流对象附加功能。

1.3 File类

因为在Java中使用流对象,操作文件是作对的使用方法。

一个用来表示文件或目录的类。

(1) 构造方法

public File(String pathname)

        通过将给定的路径名字符串转换为抽象路径名来创建新的File实例

        String数据类型的参数:在编写路径过程中,要使用到D:\xxx.png。在这里一定要注意"\\"或"/"

File file = new File("F:\\1801971.gif");//"\"是转义符不可单独使用
File file = new File("F:/1801971.gif");//"/"在路径名中可以代替"\"的作用。

(2) 两个静态常量

目录分隔符:一个路径中每级目录之间的分隔

System.out.println(File.separator);

路径分隔符:多个路径之间分隔的符号

System.out.println(File.pathSeparator); 

 1.4 四个流父类

字节与字符。输入与输出。

在Java中为以下四个类分别创建了父类

字节输入:InputStream

字节输出:OutputStream

字符输入:Reader

字符输出:Writer

以上的四个父类都是抽象类。都需要使用父类的子类才可以使用。

每一个子类都对应一种数据源对象。

例如:操作文件的输入流,FileInputStream。

1.5 流操作的基本流程

基本流程分三步:

1 打开流对象

2 操作流对象

3 关闭流对象(一定要执行)

1.6 FileInputStream和FileOutputStream

FileInputStream和FileOutputStream 是操作文件的字节流。

字节流每次操作一个字节。字节是byte。基本数据类型。是-128~127

字节是计算机文件的最小单位。使用字节流可以操作任意类型的文件。

一般都是用来操作像,图片,音频,视频这种二进制文件。

public static void main(String[] args) throws IOException {
    //第一步:打开
    FileInputStream fis = new FileInputStream("F:/Oracle-Cork.jpg");
    FileOutputStream fos = new FileOutputStream("F:/Cork.jpg");
    //第二步:操作
    byte[] bytes = new byte[1024];//1024个字节的数组。1KB
    int len = -1;//len表示本次读了多少个字节。
    while ((len = fis.read(bytes)) != -1) {
        fos.write(bytes,0,len);
    }
    //第三步:关闭
    fos.flush();//清空缓存
    fos.close();
    fis.close();
    System.out.println("end");
}

1.7 异常在IO操作中的应用

异常:try - catch - finally

IO操作工程中一定要有关闭的过程。一定要执行的部分。

第一版:旧的

public static void main(String[] args){
    //第一步:打开
    FileInputStream fis = null;
    FileOutputStream fos = null;
    try {
        fis = new FileInputStream("F:/Oracle-Cork.jpg");
        fos = new FileOutputStream("F:/Cork.jpg");
        //第二步:操作
        byte[] bytes = new byte[1024];//1024个字节的数组。1KB
        int len = -1;//len表示本次读了多少个字节。
        while ((len = fis.read(bytes)) != -1) {
            fos.write(bytes, 0, len);
        }
    }catch (IOException e){
        e.printStackTrace();
    }finally {
        //第三步:关闭
        try {
            if(fos!=null) {
                fos.flush();//清空缓存
                fos.close();
            }
            if(fis!=null) {
                fis.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    System.out.println("end");
}

第二版:新的方式

try - resour方式。

使用这种新格式,可以自动实现流对象的关闭。

try{

        声明流对象,这个流对象在使用完成之后。可以自动关闭。

}{

        try块的代码,流对象的操作

}catch(Exception e){

}

public static void main(String[] args){
    try(//第一步:打开
        FileInputStream fis = new FileInputStream("F:/Oracle-Cork.jpg");
        FileOutputStream fos = new FileOutputStream("F:/Cork.jpg"); ) {
        //第二步:操作
        byte[] bytes = new byte[1024];//1024个字节的数组。1KB
        int len = -1;//len表示本次读了多少个字节。
        while ((len = fis.read(bytes)) != -1) {
            fos.write(bytes, 0, len);
        }
    }catch (IOException e){
        e.printStackTrace();
    }
    System.out.println("end");
}

1.8 FileWriter 和 FileReader

FileWriter      字符输出流

FileReader   字符输入流

字符流一般用来操作文本文件

每次读写一个字符

1.9 BufferedReader 和 BufferedWriter

两个带缓存的字符输入流和字符输出流对象。

这两个是过滤流对象。不直接操作源对象。直接操作的是另一个流对象。

过滤流是对节点流功能的扩展

Buffered 是扩展的缓存

BufferedReader测试代码:

public class FileReaderTest {
    public static void main(String[] args) {
        try (FileReader fileReader = new FileReader("f:/b.txt");//节点流
             BufferedReader br = new BufferedReader(fileReader);//过滤流
        ) {
            while(br.ready()) {
                String s = br.readLine();
                System.out.println(s);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

BufferedWriter测试代码:

public class FileWriterTest {
    public static void main(String[] args) {
        try (FileWriter fw = new FileWriter("f:/b.txt");
             BufferedWriter bw = new BufferedWriter(fw)) {
            bw.write("这是一行文本!!");
            bw.newLine();
            bw.write("这是一行新文本!!!");
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

1.10 使用第三方插件

commons-io.jar。 这是第三方提供的Jar包。

Jar包是个class文件的压缩包。可以在Java工程中导入。

当我们以后编写好了一些类。想让其他程序员也能使用。我们要做的就是将自己的Java 类打包。打成Jar包。

FileUtilsTest测试代码(两个文件之间的复制推荐用这个):

public class FileUtilsTest {
    public static void main(String[] args) {
        try {
            FileUtils.copyFile(
                    new File("f:/Cork.jpg"),
                    new File("f:/Cork-1.jpg"));
            System.out.println("end");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

IOUtilsTest测试代码(当其中一方不是文件时推荐使用这个):

public class IOUtilsTest {
    public static void main(String[] args) {
        try {
            IOUtils.copy(
                    new FileInputStream("F:/Oracle-Cork.jpg"),
                    new FileOutputStream("F:/Cork-2.jpg"));
            System.out.println("end");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1.11 序列化和反序列化

(1) 什么叫序列化和反序列化

化:过程。

序列化:将对象保存到文件的过程称为序列化。

反序列化:从文件中读一个对象的过程称为反序列化。

例:

单机游戏存档

        1 save 存档 序列化。

        2 load 读档 反序列化。

(2) 序列化接口Serializable

接口表示了一种能力。当我们字节编写的类实现了某一个接口就表示具备了某一种能力。

Serializable接口:

public interface Serializable{
}

这个接口中没有任何方法。只表示了一种能力。

我们自己编写的类。实现了Serializable接口,才能被序列化和反序列化。

/**
 * Goods类实现了Serializable接口。表示Goods类可以被序列化和反序列化。
 */
public class Goods implements Serializable {
    private Integer goodsId;
    private String goodsName;
    private Double goodsPrice;
}

(3) 序列化使用的流对象

序列化操作是输入还是输出?输出

对象的类型是很多种,所以使用字节流

序列化是将对象保存到文件的过程。使用操作文件的流对象。

能确定第一个节点流对象:FileOutputStream

还需要一个过滤流对象:ObjectOutputStream。

public static void main(String[] args) {
    try (
            FileOutputStream fos = new FileOutputStream("f:/obj.data");
            ObjectOutputStream oos = new ObjectOutputStream(fos)
    ) {
        Goods goods = new Goods(1,"小米13Pro",3900D);
        oos.writeObject(goods);
        System.out.println("end");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

1.12 资源文件

资源文件是一个以.properties为后缀的文本文件

资源文件还是一个Key - Value的文本文件。一定要符合Map接口的格式。

在资源文件中所有内容都是如下格式编写的:

ps:中文转码的工具是:JAVA_HOME/bin/native2ascii.exe

 1.13 Properties类

Properties类是用来专门操作资源文件的类。

Properties是Map接口的一个实现类。

Properties也是一种Key - Value的集合类

我们使用Properties对象来加载资源文件中的内容。

加载的过程徐娅使用到流对象进行文件加载。

(1) 构造方法

public Properties()

        创建一个没有默认值的空属性列表。

//创建了一个空的Properties对象
Properties properties = new Porperties();

(2) 加载资源文件

        将一个资源文件(.Properties)中的内容全部加载到Properties对象中。

        public void load(Inputstream instream)throwsIOException

                从输入字节流读取属性列表(键和元素对)。

//加载资源文件
InputStream is = new FileInputStream("F:\\202301 31-tu3\\src\\IOProj01\\src\\test.properties");
properties.load(is);

优化路径:在使用流对象时,不要使用绝对路径。

        使用当前类的路径。

InPutStream is = Properties.class.getResourceAsStream("/test.properties");
properties.load(is);

//getResourceAsStream(); 基于当前类的路径位置去创建流对象。

(3) 获取资源文件中的值,按Key取Value

        public String getProperty(String key)

                使用此属性列表中指定的键搜索属性

//可以从Properties对象中获取资源文件中的内容。按Key取Value
String username = properties.getProperty("username");
System.out.println(username);
String password = properties.getProperty("password");
System.out.println(password);

1.14 封装操作资源文件的工具类

封装继承多态是Java的三大特点,在操作资源文件时编写的工具类就是封装的使用。

Properties类是用来操作资源文件的类。使用Properties实现的具体的功能。

我们可以将这些操作封装成一个工具类。

1 操作资源文件的行为有:

       和写

2 使用Properties操作资源文件

        在类声明Properties对象

3 引文这是一个工具类。没有必要创建实例。都是用static

/**
 * 这是一个封装操作资源文件的工具类
 */
public class PropertiesUtils {
    private final static Properties PROPERTIES = new Properties();
    static {
        //加载资源文件
        try(InputStream is = PropertiesUtils.class.getResourceAsStream("/test.properties")
        ) {
            PROPERTIES.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 按Key取Value的方法
     * @param key 关键字
     * @return Value值,如果没有对应的Key,返回null
     */
    public static String getProperty(String key){
        return PROPERTIES.getProperty(key);
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

修贤323

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值