Java编程——数据的存储以及IO流的概述

IO:输入流InputStream 输出流OutputStream

通常在软件开发项目中,长期保存数据的办法主要有两类:一类是使用数据库保存,相关的内容会在本书的 JDBC 一章做详细介绍;另外一类就是把数据保存在文件中,这也是本章讲解的重点——使用 IO 和 XML 存取数据。

Java中的IO流是输⼊输出流。输⼊流指的是将数据以字符或字节形式从外部媒介⽐如⽂件、数据库等读取到内存中所以也分为字符输⼊流和字节输⼊流。 输出流指的是将内存中的数据写⼊外部媒介,也分为了字符输出流和字节输出流。举个简单的例子可以理解为将输⼊和输出两个端点看作是两个⼯⼚,⼯⼚之间需要互相运输货物,⽽流则是两⼯⼚之间的公路,没有公路就不能互相运输,⾄于字符,字节和⼆进制则可以看作是运输的⽅式和单位⼤⼩。

  • File 类在 java.io 包下

一、关于file类的 API

file.isFile()==true?"文件":"非文件";

file.isDirectory()==true?"目录":"非目录";

相对路径:file.getPath();

绝对路径:file.getAbsolutePath();

相对路径和绝对路径:

  • 如果file("绝对路径"):getPath()和getAbsolutePath()的打印结果一致,打印的都是绝对路径

  • 如果file("相对路径"):getPath()打印相对路径,getAbsolutePath()的打印绝对路径

文件名称:file.getName();

文件大小:file.Length();单位是字节

创建文件:file.createNemFile();

删除文件:file.Delete(); //彻底删除

判断文件是否存在:file.exists();

针对以上方法的实现代码:

import java.io.*;
public class TestFile{
    public static void main(String args[]) throws IOException {
        System.out.print("文件系统根目录");
        for (File root : File.listRoots()) {
            //format方法以格式化形式输出字符串
            System.out.format("%s ", root);
        }
        System.out.println();
        showFile();
    }
​
    public static void showFile() throws IOException{
        //创建File类对象file,注意使用转义字符 `\`
        File f = new File("/home/project/Vehicle.java");
        File f1 = new File("/home/project/Vehicle1.java");
​
        //当不存在该文件时,创建一个新的空文件
        f1.createNewFile();
        System.out.format("输出字符串:%s%n", f);
        System.out.format("判断File类对象是否存在:%b%n", f.exists());
        //%tc,输出日期和时间
        System.out.format("获取File类对象最后修改时间:%tc%n", f.lastModified());
        System.out.format("判断File类对象是否是文件:%b%n", f.isFile());
        System.out.format("判断File类对象是否是目录:%b%n", f.isDirectory());
        System.out.format("判断File类对象是否有隐藏的属性:%b%n", f.isHidden());
        System.out.format("判断File类对象是否可读:%b%n", f.canRead());
        System.out.format("判断File类对象是否可写:%b%n", f.canWrite());
        System.out.format("判断File类对象是否可执行:%b%n", f.canExecute());
        System.out.format("判断File类对象是否是绝对路径:%b%n", f.isAbsolute());
        System.out.format("获取File类对象的长度:%d%n", f.length());
        System.out.format("获取File类对象的名称:%s%n", f.getName());
        System.out.format("获取File类对象的路径:%s%n", f.getPath());
        System.out.format("获取File类对象的绝对路径:%s%n",f.getAbsolutePath());
        System.out.format("获取File类对象父目录的路径: %s%n", f.getParent());
    }
}

测试结果如下所示:

System.out.format(format, args) 表示使用指定格式化字符串输出,其中 format 参数为格式化转换符。关于转换符的说明如下表所示:

转换符说明
%s字符串类型
%c字符类型
%b布尔类型
%d整数类型(十进制)
%x整数类型(十六进制)
%o整数类型(八进制)
%f浮点类型
%e指数类型
%%百分比类型
%n换行符
%tx日期与时间类型( x 代表不同的日期与时间转换符)

关于路径分隔符的使用:

import java.io.File;
public class TestFileSeparator {
    public static void main(String[] args) {
        System.out.println("PATH分隔符:" + File.pathSeparator);
        System.out.println("路径分隔符:" + File.separator);
    }
}

二、流

流:是一种FIFO(先进先出)的数据结构

 

(一)按照流向(以内存为参照点)分:

输入流                                输出流

  • 1、输入流(java.io.InputStream抽象类/Reader)-->表示字节流形式的输入流/字符流形式的输入流

    • 就是把一个文件通过输入流读入到内存中去

import java.io.*;
public class test{
    public static void main(String args[])  {
        InputStream in = null;
        try {
            in = new FileInputStream(new File("d:/test.txt"));
            System.out.println(in.available());
            //in.available(),表示文件的大小
            byte[] buf = new byte[in.available()];
            in.read(buf);   //将文件test.txt内容读取到buf中,即内存中去
            //因为buf现在是一个字节数组,所以先要转换成字符串才能显示,buf-->String
            System.out.println(new String(buf));//打印文件里面的内容
        }catch(Exception e){
            e.printStackTrace();
        }finally {
            //流一般是要关闭的,而且一般放在finally里面
            try {
                in.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
  • 2、输出流(java.io.OutputStream抽象类/Writer)-->表示字节流形式的输出流/字符流形式的输出流

    • 就是把内存中的内容通过输出流写入到文件中去

import java.io.*;
public class test{
    public static void main(String args[])  {
        OutputStream out = null;
        try {
            out = new FileOutputStream(new File("d:/test.txt"));
            out.write("重新输入的······".getBytes());  //内存-->test.txt
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                out.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
  • 文件的复制

 

在文件复制过程中会出现以下几种情况:

因为文件有可能过大,所以需要分次进行读取,而假设每次读取的字节数为10,则最后一次读取完之后,下次想要读取时则返回-1(len)时,也就是已经将文件中的内容全部读取到内存中去了。。

        总体的复制过程就是每次读取到内存中,然后再输出,再进行下一次的读取,,上次读取完10个字节后,下次读取时,该10个字节会完全覆盖上次读取时的10个字节,,,意思就是内存(缓冲区的大小是10个字节),但是最后一次复制时文件中就只剩下2个字节(比如qw)时,则会将上次缓冲区(比如1234567890)的8个字节作为最后一次的复制内容(即qw34567890),,出现这种情况的解决方法是:在最后一次输出时,输出从0开始,到最后一次热read()的返回值len;

import java.io.*;
public class test{
    //test.txt-->内存-->out
    public static void main(String args[])  {
        OutputStream out = null;
        InputStream in = null;
        try {
            in = new FileInputStream(new File("d:/test.txt"));//这里也可以传输图片、视频等其它文件
            out = new FileOutputStream(new File("d:/new.txt"));//这里也可以传输图片、视频等其它文件
            //test.txt-->内存
            //开辟10个字节的内存数组
            byte[] buf = new byte[10];
            int len = -1;
            while ( (len=in.read(buf))!=-1){
                //内存-->out
                out.write(buf,0,len);
            }
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                if(in !=null)in.close();
                if(out !=null)out.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
​
        }
    }
}
  • 以上三种都是使用字节流实现文件的输入/输出以及文件的复制

说明:在while循环中 分批次传输时,字节流使用的缓冲区是byte[ ]类型的数组,字符流使用的缓冲区是char[ ]类型的数组

(二)按照处理单位分:

  • 1、字节流:就是将文件内容以字节形式进行传输,1字节-->8bit,二进制可以传输任何类型的数据,因此字节流也可以传输任何类型的数据。(其中包括文件、图片、视频、压缩包等等,基本上都是除了文本文件以外的所有文件)

    FileInputStream、 FileOutputStream       //既是字节流也是输入输出流(之前在复制文件时用到过)
  • 2、字符流:是16位的unicode字符流(只用于处理字符,文本文件)Reader/writer

每次往内存中读取一次就拼接一次(就是每次把内存中的读取数据拼接成完整的数据,可用一个字符串[StringBuffer]来拼接)

import java.io.*;
public class test{
    //简介.txt-->内存-->拼接-->替换占位符-->完整简介
    public static void main(String args[])  {
        //文件-->内存(reader)
        Reader reader =null;
        Writer writer =null;
        try {
            reader = new FileReader(new File("d:/简介.txt"));
            writer = new FileWriter(new File("d:/完整简介.txt"));
            char[] buf = new char[4];
            StringBuffer sb = new StringBuffer();
            int len = -1;
            while ((len = reader.read(buf))!=-1){
                //内存-->拼接
                sb.append(buf,0,len);
            }
            //内存-->拼接-->替换占位符
            String content = sb.toString();//将StringBuffer()利用toString()转换成String
            /*content=content.replace("{name}","王福昌");
            content=content.replace("{place}","甘肃");
            content=content.replace("{课程}","java");*/
            //也可以简写为:
            content=content.replace("{name}","王福昌")
                     .replace("{place}","甘肃")
                     .replace("{课程}","java");
            //将替换后的内容输出到新文件中:替换占位符-->完整简介
            writer.write(content);
            System.out.println("成功");
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
​
                try {
                    if(reader!=null)reader.close();
                    if(reader!=null)writer.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
        }
    }
}

支持:🎁🎁🎁如果你觉得博主的文章的不错或者对你有帮助,可以点一个免费的关注支持一下博主,如果三连收藏支持就更好了吖,嘿嘿嘿,蟹蟹。 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

-今非昔比°

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

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

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

打赏作者

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

抵扣说明:

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

余额充值