JAVA-IO流

用于读写文件的“流”

流的分类:

  • 按文件类型:
    • 字节流:可以操作所有类型的文件
    • 字符流:只能操作纯文本文件
  • 按流向:
    • 输出流
    • 输入流

流的结构:

java.io
│
├── 字节流
│   ├── InputStream  字节输入流
│   │    ├── FileInputStream
│   │    ├── FilterInputStream
│   │    │     ├── BufferedInputStream  缓冲字节输入流
│   │    │     └── DataInputStream
│   │    └── ObjectInputStream  反序列化流
│   └── OutputStream  字节输出流
│         ├── FileOutputStream
│         ├── FilterOutputStream
│         │     ├── BufferedOutputStream  缓冲字节输出流
│         │     └── DataOutputStream
│         └── ObjectOutputStream  序列化流
│
└── 字符流
    ├── Reader  字符输入流
    │     ├── FileReader
    │     ├── FilterReader
    │     │     ├── BufferedReader  缓冲字符输入流
    │     │     └── LineNumberReader
    │     └── InputStreamReader
    └── Writer  字符输出流
           ├── FileWriter
           ├── FilterWriter
           │     ├── BufferedWriter  缓冲字符输出流
           │     └── PrintWriter
           └── OutputStreamWriter

1.字节流:

1.1 文件字节输出流:FileOutputStream

创建字节输出流对象:

  • 参数可以是字符串路径、File对象
  • 文件不存在则会创建新文件,但要保证父级路径正确
  • 文件已存在,默认覆盖
  • 需要续写,则需要在创建时在第二个参数处填 true。

写入数据:

  • 写入参数对应ASCII码
方法名称说明
void write(int b)一次写一个字节数据
void write(byte[] b)一次写一个字节数组数据
void write(byte[] b, int off, int len)一次写一个字节数组的部分数据

其他类型可以使用方法:对象.getBytes();

换行:

写入换行符:

  • windows: \r\n (只写一个JAVA会自己补全)
  • Linux: \n
  • Mac: \r

释放资源/关流:

  • f.close();

1.2 文件字节输入流: FileInputStream

创建字节输入流对象:

  • 参数可以是字符串路径、File对象
  • 文件不存在则直接报错

读取数据:

  • 读出返回值为字符对应ASCII码
  • 读到文件末尾,read()返回-1
方法名称说明
public int read()一次读一个字节数据
public int read(byte[] buffer)一次读一个字节数组数据(会尽可能填满)

循环读取示例:注意此处临时变量b的必要性

        FileInputStream fis =new FileInputStream("src/aaa.txt");

        int b;
        while ((b=fis.read())!=-1){
            System.out.print((char)b);
        }

释放资源/关流:

  • f.close();


2 字符流

字符流=字节流+字符集

2.1 文件字符输入流:

创建对象:

  • FileReader(File file)
  • FileReader(String pathname)

细节同上

读取:

  • public int read() : 读取单个字符,读到末尾返回-1
  • public int read (char[] buffer) : 读取多个数据,读到末尾返回-1

细节:

  • 按字节读取,遇到中文,一次读多个字节,读取后解码,返回对应整数
  • 释放资源/关流:f.close();
  • 返回的是十进制,可用(char)强制类型转换

2.2 文件字符输出流:

构造对象:

FileWriter()同FileOutputStream,有重载的两个参数,第二个参数append为true时续写。

写出:

成员方法说明
void write(int c)写出一个字符(整数对应字符)
void write(String str)写出一个字符串
void write(String str, int off, int len)写出一个字符串的一部分
void write(char[] cbuf)写出一个字符数组
void write(char[] cbuf, int off, int len)写出字符数组的一部分

3 综合案例:

3.1 拷贝整个文件夹:

import java.io.*;

public class Main{
    public static void main(String[] args) throws IOException {
        //拷贝文件源
        File src=new File("D:\\My Java Code\\filetest\\aaa");
        //拷贝文件目标
        File target = new File("D:\\My Java Code\\filetest\\target");
        
        copyFile(src,target);
    }
    private static void copyFile(File src,File target) throws IOException {
        target.mkdirs();//确保目标目录存在。

        File[] files=src.listFiles();

        for (File file:files){
            //如果是文件,拷贝;否则递进入文件夹
            if(file.isFile()){
                FileInputStream fis=new FileInputStream(file);
                FileOutputStream fos=new FileOutputStream(new File(target,file.getName()));

                byte[] bytes=new byte[1024];
                int len=0;
                while((len=fis.read(bytes))!=-1){
                    fos.write(bytes,0,len);
                }

                fos.close();
                fis.close();
            }else {
                copyFile(file,new File(target,file.getName()));
            }
        }
    }
}

4 缓冲流:BufferedStream

缓冲流(Buffered Streams)和普通IO流(Non-buffered Streams)在Java中都是用于输入和输出操作的,通过减少实际的读写操作次数,缓冲流可以显著提高性能。适用于对性能要求较高或数据量较大的场景,如文件复制、大数据处理等。

缓冲流在创建时需要一个基本流对象,并且在使用时提供了与基本流相似的方法。

缓冲区默认大小:8192

字符缓冲流:

  • public BufferedReader(Reader r)
    • 特有方法:public String readLine() :读取一行数据,读不到返回null。(不会读入换行)
  • public BufferedWriter(Writer w)
    • 特有方法:public void newLine() :跨平台的换行
    • 特有方法:public void flush(): 刷新缓冲区,常与newLine一起使用。

另外,要开启续写,要在对应基本流里写append。

5 转换流

转换流主要有两种类型:InputStreamReader 和 OutputStreamWriter。

高级流,所以构造方法参数为基本流。

转换流可以将一个字节流包装成字符流,或者将一个字符流包装成字节流。这种转换通常用于处理文本数据,如读取文本文件或将数据从网络传输到应用程序。

6 序列流

Java 的序列流(ObjectInputStream 和 ObjectOutputStream)是一种可以将 Java 对象序列化和反序列化的流。

6.1 序列化流 :Object OutputSteam:

条件:

  • 只有实现了 Serializable 接口的对象才能被序列化。(一个标记型接口)
  • 该类的所有字段都必须是可序列化的。如果一个字段不需要序列化,则需要使用transient 关键字 进行修饰。

构造方法:

也是一个高级流,所以构造方法参数为基本流。

ObjectOutputStream(OutputStream out)

写出方法:

oos.writeObject (Object obj)

6.2 反序列化流:ObjectInputStream

构造方法:

ObjectInputStream(InputStream in) 

读入方法:

oos.readObject(Object obj)返回一个Object 对象,需要再次进行强转。

序列版本号:serialVersionUID:

序列化一个对象后,更改javabean类,就会改变它的版本号。再次反序列化时,版本号不一致就会报错。

解决:手动添加serialVersionUID。

private static final long serialVersionUOD=65465156L;

7 打印流 PrintStream 、PrintWrite:

  • 打印流只输出目的地,不操作数据源
  • 特有的写出方法可以让数据原样写出
  • 特有的写出方法可以自动刷新、自动换行

8 IO工具包

8.1:commons.io

Apache Commons IO是一个Apache的jar包,使用前需要导入到lib中。

主要功能:

  • 工具类:提供静态方法来执行常见任务,如IOUtilsFileUtilsFilenameUtilsFileSystemUtils
  • 输入和输出:提供InputStreamOutputStream的实现,以及ReaderWriter的实现。
  • 过滤器:提供多种文件过滤器实现,定义了IOFileFilter接口,同时继承了FileFilterFilenameFilter接口。
  • 比较器:提供用于文件比较的多种java.util.Comparator实现。
  • 文件监控:提供组件用于监控文件系统事件(目录和文件的创建、更新和删除事件)

8.2:Hutool工具类库

更加全面、边查边用。

9 综合案例:网络爬虫

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main{
    public static void main(String[] args) throws IOException {
        //记录网址
        String familyNameNet="https://hanyu.baidu.com/shici/detail?pid=0b2f26d4c0ddb3ee693fdb1137ee1b0d";

        //爬取数据
        String familyNameTempStr=webCrawler(familyNameNet);

        //清洗数据
        ArrayList<String> familyNameTempList =getData(familyNameTempStr,"(.{3}[^tem\"\\>])(,|。)");

        //提取单个姓氏
        ArrayList<String>familyNameList=new ArrayList<>();
        for (String temp:familyNameTempList){
            for (int i = 0; i < temp.length(); i++) {
                char c=temp.charAt(i);
                familyNameList.add(c+"");
            }
        }

        //得到信息  姓名-性别-年龄
        ArrayList<String>infos=getInfos(familyNameList,30);

        //写入文档
        FileWriter fileWriter=new FileWriter("D:\\My Java Code\\filetest\\name.txt");
        BufferedWriter bufferedWriter=new BufferedWriter(fileWriter);

        for (String info:infos){
            bufferedWriter.write(info);
            bufferedWriter.newLine();
        }
        
        bufferedWriter.close();
        fileWriter.close();

    }

    private static ArrayList<String> getInfos(ArrayList<String> familyNameList, int num) {
        ArrayList<String>infos=new ArrayList<>();
        Random random=new Random();

        //随机得到不重复的姓名
        HashSet<String> hs=new HashSet<>();
        while (true){
            if (hs.size()==num)
                break;
            Collections.shuffle(familyNameList);
            hs.add(familyNameList.get(0)+"建国");
        }

        //随机性别
        String[] gender={"男","女"};

        //组合
        for (String name:hs) {

            int genderIndex=random.nextInt(2);

            //随机年龄
            Integer age =random.nextInt(10)+18;
            String ageStr=age.toString();

            infos.add(name +"-"+gender[genderIndex]+"-"+ageStr);
        }

        return infos;
    }

    private static ArrayList<String> getData(String str, String regex) {
        ArrayList<String> list=new ArrayList<>();

        Pattern pattern= Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);

        while (matcher.find()){
            String group=matcher.group(1);
            list.add(group);
            //System.out.println(group);
        }

        return list;
    }

    private  static  String webCrawler(String net) throws IOException {
        //定义sb拼接爬取到的数据
        StringBuilder sb =new StringBuilder();
        //创建URL对象
        URL url=new URL(net);
        //链接这个网址
        URLConnection connection = url.openConnection();
        //读取数据
        InputStreamReader isr=new InputStreamReader(connection.getInputStream());

        int ch;
        while ((ch=isr.read())!=-1){
            sb.append((char) ch);
        }
        isr.close();

        return sb.toString();
    }
}

得到:info.txt

池建国-女-25
文建国-男-25
彭建国-男-26
巫建国-女-19
扶建国-女-25
宣建国-女-25
鲍建国-男-27
满建国-女-20
戴建国-男-18
卓建国-女-20
樊建国-男-25
俞建国-女-20
裘建国-女-19
桂建国-女-24
汲建国-女-25
凤建国-女-20
融建国-男-18
年建国-女-22
娄建国-女-25
易建国-男-20
诸建国-女-22
木建国-女-23
鞠建国-女-21
云建国-女-25
禹建国-女-20
丘建国-女-18
束建国-男-18
郜建国-女-24
丌建国-男-26
茅建国-女-18
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇