第三周预习-JavaIO流

File

1.概念

存储数据的方案:变量、数组、对象、集合,他们都是内存中的数据,在断电或者程序终止时会丢失;文件是保存数据的地方,在计算机硬盘中,即使断电或者程序终止,存储在硬盘的数据不会丢失,可以长久保存数据。
File类只能对文件本身进行操作,不能读写文件里面存储的数据
IO流:用于读写数据(可以读写文件、网络中的数据)

  • 文件流:文件在程序中是以流的形式来操作的
  • 流:数据在数据源(文件)和程序(内存)之间经历的路径
  • 输入流:数据在数据源(文件)到程序(内存)的路径
  • 输出流:数据从程序(内存)到数据源(文件)的路径

2.常用操作

  • 创建文件对象
构造器说明
File(String pathname)根据路径构造一个File对象
File(File parent,String child)根据父目录文件+子路径构建
File(String parent,String child)根据父目录+子路径构建

方法:public boolean createNewFile() 创建新文件

import java.io.File;
import java.io.IOException;

public class FileCreat {
    public static void main(String[] args) {
        //方式一
            String filePath1 = "d:/news1.txt";
            File file1 = new File(filePath1);
            try {
                file1.createNewFile();
                System.out.println("文件创建成功");
            } catch (IOException e) {
                e.printStackTrace();
            }
        //方式二
            File parentfile2 = new File("d:\\");
            String filePath2 = "news2.txt";
            File file2 = new File(parentfile2,filePath2);
            try {
                file2.createNewFile();
                System.out.println("文件创建成功");
            } catch (IOException e) {
                e.printStackTrace();
            }
        //方式三
            String parentPath3 = "d:\\";
            String filePath3 = "news3.txt";

            File file3 = new File(parentPath3,filePath3);
            try {
                file3.createNewFile();
                System.out.println("文件创建成功");
            } catch (IOException e) {
                e.printStackTrace();
            }
    }

}

在这里插入图片描述

  • 获取文件信息
方法名称说明
public boolean exists()判断当前文件对象,对应的文件路径是否存在
public boolean isFile()判断当前文件对象指代的是否是文件
public boolean isDirectory()判断当前文件对象指代的是否是文件夹
public String getName()获取文件的名称(包含后缀)
public long length()获取文件的大小,返回字节个数
public long lastModified()获取文件的最后修改时间
public String getPath()获取创建文件对象时使用的路径
public String getAbsolutePath()获取绝对路径
public String getParent()获取文件父级目录
import java.io.File;
import java.text.SimpleDateFormat;

public class FileInformation {
    public static void main(String[] args) {
        File file = new File("d:\\news1.txt");
        System.out.println("文件名字="+file.getName());//文件名字=news1.txt
        System.out.println("创建文件对象时,使用的路径="+file.getPath());//创建文件对象时,使用的路径=d:\news1.txt
        System.out.println("文件绝对路径="+file.getAbsolutePath());//文件绝对路径=d:\news1.txt
        System.out.println("文件父级目录="+file.getParent());//文件父级目录=d:\
        System.out.println("文件大小(字节)="+file.length());//文件大小(字节)=11
        System.out.println("文件是否存在="+file.exists());//文件是否存在=true
        System.out.println("是不是一个文件="+file.isFile());//是不是一个文件=true
        System.out.println("是不是一个目录="+file.isDirectory());//是不是一个目录=false
        long time = file.lastModified();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        System.out.println("最后修改时间="+sdf.format(time));//最后修改时间=2024/04/04 08:19:59
    }
}
  • 目录的操作和文件删除
方法名称说明
public boolean mkdir()只能创建一级文件夹
public boolean mkdirs()可以创建多级文件夹
public boolean delete()删除文件、空文件夹
import java.io.File;

public class Directory {
    public static void main(String[] args) {
        //创建一级文件
        File file1 = new File("d:\\demo");
        System.out.println(file1.mkdir());//true
        //创建多级文件
        File file2 = new File("d:\\demo\\a\\b\\c");
        System.out.println(file2.mkdirs());//true
        //删除文件
        File file3 = new File("d:\\news1.txt");
        System.out.println(file3.delete());//true
        //删除空文件夹
        System.out.println(file2.delete());//true
    }
}
  • 遍历文件夹
方法名称说明
public String[ ] list()获取当前目录下的所有“一级文件名称”到一个字符串数组中去返回
public File[ ] listFiles()获取当前目录下的所有“一级文件对象”到一个文件对象数组中去返回
import java.io.File;

public class FileTest1 {
    public static void main(String[] args) {
        File f1 = new File("D:\\demo");
        String[] names = f1.list();
        for (String name : names){
            System.out.print(name);
        }
        File[] files = f1.listFiles();
        for(File file:files){
            System.out.print(file.getAbsoluteFile());
        }
    }
}

使用listFiles方法时的注意事项:

  1. 当主调是文件或路径不存在时,返回null
  2. 当主调是空文件夹时,返回一个长度为0的数组:[ ]
  3. 当主调是一个有内容的文件夹时,将里面所有一级文件和文件夹的路径放在File数组中返回
  4. 当主调是一个文件夹,且里面有隐藏文件时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件
  5. 当主调是一个文件夹,但是没有权限访问该文件夹时,返回null

(找多级文件,实现文件搜索,需要运用方法递归)

Path

Java.nio.file.Path接口类似于Java.io.File类,许多情况下,可以使用Path接口替换File类的使用
使用Path类进行路径中文件名的获取

  • 创建Path对象:Path.get()
import java.nio.file.Path;
import java.nio.file.Paths;

public class PathDemo {
    public static void main(String[] args) {
        //使用绝对路径创建
        Path absolutePath = Paths.get("E:\\Java\\myio\\a.txt");
        //使用相对路径创建
        Path relativePath = Paths.get("E:\\Java\\myio","a.txt");
        System.out.println(absolutePath.equals(relativePath));//ture
    }
}
  • Paths类方法
方法描述
static Path get(String first,String …)根据给定的路径字符串和更多路径字符串创建Path对象,允许使用多个字符串片段来构建路径
static Path (URI uri)根据给定的URI创建Path对象
static Path get(Path path)根据给定的Path对象创建新的Path对象
  • Path接口方法
方法描述
Path getFileName()返回路径中的文件名部分
Path getParent()返回路径中的父路径
Path resolve(String other)解析给定的路径字符串,并返回一个新的Path对象,该对象表示将当前路径与给定路径合并后的结果
Path normalize()返回规范化的路径,去除多余的目录分隔符、'.‘和’…'等元素
Path toAbsolutePath()返回当前路径的绝对路径

IO流原理及流的分类

1.Java IO流原理

  • 用于处理数据传输,如读写文件、网络通讯等。
  • Java程序中,对于数据的输入输出操作以流的方式进行
  • java.io包下提供了各种流类和接口,用于获取不同种类的数据,并通过方法输入或输出数据
  • 输入input:读取外部数据(磁盘、光盘、数据库、网络等存储设备的数据)到程序(内存)中
  • 输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中

2.流的分类

  • 按操作数据单位:字节流(8 bit)(二进制文件)、字符流(按字符)(文本文件)
  • 按数据流的流向:输入流、输出流
  • 按流的角色:节点流,处理流/包装流
抽象基类字节流字符流
输入流InputStreamReader
输出流OutputStreamWriter

IO流

字节流

1.FileInputStream

操作本地文件的字节输入流,可以把本地文件中的数据读取到程序中来
步骤:

  1. 创建字节输入流对象:如果文件不存在,报错
  2. 读数据:一次读一个字节,读出来的是数据在ASCII上对应的数字;读到文件末尾,read方法返回-1;读取一次数据read()移动一次指针。
  3. 释放资源:每次使用完流之后都要释放资源
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamDemo {
    public static void main(String[] args) throws IOException {
        //1.创建对象
        FileInputStream fis = new FileInputStream("E:\\Java\\myio\\a.txt");
        //2.循环读取
        int b;
        while((b=fis.read())!=-1){
            System.out.println((char)b);
        }
        //3.释放资源
        fis.close();
    }
}

2. FileOutputStream

操作本地文件的字节输出流,可以把程序中的数据写到本地文件中

步骤:

  1. 创建字节输出流对象:参数可以是字符串表示的路径或File对象;如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的;如果文件已经存在,则会清空文件。
  2. 写数据:write方法的参数是整数,但是实际上写到本地文件的是整数在ASCII上对应的字符
  3. 释放资源:每次使用完流之后都要释放资源

FileOutputStream写数据的三种方式

方法名称说明
void write(int b)一次写一个字节数据
void write(byte[ ] b)一次写一个字节数组数据
void write(byte[ ] b,int off,int len)一次写一个字节数组的部分数据
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamDemo {
    public static void main(String[] args) throws IOException {
        //1. 创建字节输出流对象
        FileOutputStream fos = new FileOutputStream("E:\\Java\\myio\\a.txt");
        // 2. 写数据
        //方式一
        fos.write(97);
        //方式二
        byte[] bytes={97,98,99,100};
        fos.write(bytes);
        //方式三
        fos.write(bytes,0,3);
        //3. 释放资源
        fos.close();
    }
}

a.txt :aabcdabc

换行和续写
换行:windows \r\n或\r或\n
续写:创建对象的第二个参数默认false,表示关闭续写,创建对象会清空文件;手动传递true,表示打开续写,创建对象不会清空文件。

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class FileOutputStreamDemo {
    public static void main(String[] args) throws IOException {
        //1. 创建字节输出流对象
        FileOutputStream fos = new FileOutputStream("E:\\Java\\myio\\a.txt",true);
        // 2. 写数据
        String str1 = "\r\n";
        byte[] bytes1 = str1.getBytes();
        fos.write(bytes1);
        String str2 = "666";
        byte[] bytes2 = str2.getBytes();
        fos.write(bytes2);
        //3. 释放资源
        fos.close();
    }
}

aabcdabc
666

3.文件拷贝

方法名称说明
public int read()一次读一个字节数据
public int read(byte[ ] buffer)一次读一个字节数组数据,每次读取尽可能把数组装满,长度用1024的整数倍
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo1 {
    public static void main(String[] args) throws IOException {
        //1.创建对象
        FileInputStream fis = new FileInputStream("E:\\Java\\myio\\a.txt");
        FileOutputStream fos1 = new FileOutputStream("E:\\Java\\myio\\b.txt");
        FileOutputStream fos2 = new FileOutputStream("E:\\Java\\myio\\c.txt");
        //2.拷贝:边读边写
        //方法一:一次读一个字节数据
        //int b;
        //while((b= fis.read())!=-1){
        //    fos1.write(b);
        //}
        //方法二:一次读一个字节数组数据
        int len;
        byte[] bytes = new byte[1024];
        while ((len=fis.read(bytes))!=-1){
            System.out.println("len");
            fos2.write(bytes,0,len);
        }
        //3.释放资源,先开的最后关闭
        fos2.close();
        // fos1.close();
        fis.close();
    }
}

字符流

1.字符集

  • ASCII字符集:英文用一个字节存储
  • GBK字符集:Windows系统默认使用GBK,系统显示ANSI;
    英文用一个字节存储,兼容ASCII,前面补0,二进制以0开头;
    汉字用两个字节存储,高位字节二进制以1开头,转成十进制为负数
  • Unicode字符集:国际标准字符集,将世界各种语言的每个字符定义一个唯一的编码,以满足跨语言、跨平台的文本信息交换;
    UTF-8编码规则:用1-4个字节保存;
    英文字母用一个字节表示,二进制第一位补0;
    中文汉字用三个字节表示(1110xxxx 10xxxxxx 10xxxxxx)

乱码出现原因:

1.字节流读取文本文件:一次读取一个字节(字节流读取中文会乱码,拷贝不会乱码)
2.编码和解码方式不统一

编码和解码的方法

String类中的方法说明
public byte[ ] getBytes()使用默认方式进行编码
public byte[ ] getBytes(String charsetName)使用指定方式进行编码
String (byte[ ] bytes)使用默认方式进行解码
String (byte[ ] bytes,String charsetName)使用指定方式进行解码

字符流=字节流+字符集
输入流:一次读一个字节,遇到中文时,一次读多个字节
输出流:底层会把数据按照指定的编码方式进行编码,变成字节再写到文件中

2.FileReader

  1. 创建字符输入流对象
    底层:关联文件,并创建缓冲区(长度为8192的字节数组)
构造方法说明
public FileReader(File file)创建字符输入流关联本地文件
public FileReader(String pathname)创建字符输入流关联本地文件
  1. 读数据
    底层:判断缓冲区中是否有数据可以读取;
    若缓冲区没有数据,从文件获取数据到缓冲区;
    若缓冲区有数据,就从缓冲区读取。
成员方法说明
public int read()读取数据,读到末尾返回-1,读取数据之后,进行解码转化为十进制作为返回值,若想看到中文汉字需要进行强转。
public int read(char[] buffer )读取多个数据,读到末尾返回-1,读取数据、解码、强转、将强转之后的字符放到数组中
  1. 释放资源
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class FileReaderDemo {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("E:\\Java\\myio\\a.txt");
        //空参read方法public int read()
        //int ch;
        //while((ch = fr.read())!=-1){
       //     System.out.print((char)ch);
        //}
        //public int read(char[] buffer )
        char[] chars = new char[2];
        int len;
        while ((len=fr.read(chars))!=-1){
            System.out.print(new String(chars,0,len));
        }
        fr.close();
    }
}

3.FileWriter

  1. 创建字符输出流对象
构造方法说明
public FileWriter(File file)创建字符输出流关联本地文件
public FileWriter(String pathname)创建字符输出流关联本地文件
public FileWriter(File file,boolean append)创建字符输出流关联本地文件,续写
public FileWriter(String pathname,boolean append)创建字符输出流关联本地文件,续写
  1. 写数据
成员方法说明
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)写出字符数组的一部分
  1. 释放资源
import java.io.FileWriter;
import java.io.IOException;

public class FileWriterDemo {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("E:\\Java\\myio\\a.txt",true);
        fw.write(25105);
        fw.write("你好你好",0,2);
        char[] chars = {'a','b','c','d'};
        fw.write(chars,0,2);
        fw.close();
    }
}

缓冲流

底层自带了长度为8192的缓冲区提高性能
字节缓冲流缓冲区为byte型,长度是8KB
字符缓冲流缓冲区为char型,长度是16KB
在这里插入图片描述

1.字节缓冲流

可以显著提高字节流的读写性能

方法名称说明
public BufferedInputStream(InputStream is)把基本流包装成高级流,提高读取数据的性能
public BufferedOutputStream(OutputStream os)把基本流包装成高级流,提高写出数据的性能
import java.io.*;

public class BufferedStreamDemo1 {
    public static void main(String[] args) throws IOException {
        //利用字节缓冲流拷贝文件
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\\Java\\myio\\a.txt"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:\\Java\\myio\\b.txt"));
        int b;
        while((b= bis.read())!=-1){
            bos.write(b);
        }
        bos.close();
        bis.close();
    }

2.字符缓冲流

对字符流提升不明显,关键是两个特有的方法

方法名称说明
public BufferedReader(Reader r)把基本流包装成高级流
public BufferedWriter(Writer r)把基本流包装成高级流
public String readLine()读取一行数据,如果没有数据可读,返回null
public void newLine()跨平台的换行
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedStreamDemo2 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("e:\\java\\myio\\a.txt"));
        String line;
        while ((line = br.readLine())!=null){
            System.out.println(line);
        }
        br.close();

    }
}
import java.io.*;

public class BufferedStreamDemo3 {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("e:\\java\\myio\\b.txt"));
        bw.write("abc");
        bw.newLine();
        bw.write("def");
        bw.close();

    }
}

在这里插入图片描述

转换流

是字符流与字节流之间的桥梁,使字节流可以使用字符流中的方法

1.InputStreamReader

构造方法说明
InputStreamReader(InputStream in)创建一个使用默认字符集的字符流
InputStreamReader(InputStream in,String charsetName)创建一个使用指定字符集的字符流

2. OutputStreamWriter

构造方法说明
OutputStreamWriter (OutputStream in)创建一个使用默认字符集的字符流
OutputStreamWriter (OutputStream in,String charsetName)创建一个使用指定字符集的字符流

对象流

序列化流、反序列化流

1.ObjectOutputStream

序列化流(对象操作输出流)

构造方法说明
public ObjectOutputStream(OutputStream out)把基本流包装成高级流
成员方法说明
public final void writeObject(Object obj)把对象序列化到文件中去
import java.io.Serializable;

public class Student implements Serializable {
//
    private static final long serialVersionUID = -427553587245757343L;
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    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;
    }
}


import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class ObjectOutputStreamDemo {
    public static void main(String[] args) throws IOException {
        Student stu = new Student("zhangsan",22);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\Java\\myio\\a.txt"));
        oos.writeObject(stu);
        oos.close();
    }
}

2. ObjectInputStream

反序列化流(对象操作输入流)

构造方法说明
public ObjectInputStream(InputStream in)把基本流包装成高级流
成员方法说明
public Object readObject()把序列化到本地文件中的对象,读取到程序中来
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class ObjectInputStreamDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\Java\\myio\\a.txt"));
        Object o = ois.readObject();
        System.out.println(o);
        ois.close();
    }
}

在这里插入图片描述

  • Serializable接口里面没有抽象方法,标记型接口,一旦实现了这个接口,那么就表示当前的类可以被序列化
  • 序列化写到文件中的数据不能被修改,否则无法再次读回来
  • 序列化对象后,修改了Javabean类,再次反序列化,会抛出异常,需要给Javabean类添加serialVersionUID(序列号、版本号)(先写标准Javabean,最后写serialVersionUID)
  • transient关键字标记的成员变量不参与序列化过程,读取时默认初始化值

打印流

1. PrintStream

字节打印流

构造方法说明
public PrintStream(OutputStream/File/String)关联字节输出流/文件/文件路径
public PrintStream(String fileName,Charset charset)指定字符编码
成员方法说明
public void println(Xxx xx)打印任意数据,自动刷新,自动换行
public void print(Xxx xx)打印任意数据,不换行
public void printf(String format, Object… args)带有占位符的打印语句,不换行

2.PrintWriter

字符打印流,字符流底层有缓冲区想要自动刷新需要开启

构造方法说明
public PrintWriter(Write/File/String)关联字节输出流/文件/文件路径
public PrintWriter(String fileName,Charset charset)指定字符编码
public PrintWriter(Write w,boolean autoFlush)自动刷新
public PrintWriter(OutputStream out,boolean autoFlush,Charset charset)指定字符编码且自动刷新

成员方法与字节打印流类似

数据流

  • 数据输入流:DataInputStream
  • 数据输出流:DataOutputStream
    允许程序按着机器无关的风格读取Java原始数据,不必关心数据有多少字节
方法名称说明
DataInputStream(InputStream is)创建的数据输入流指向一个由参数in指定的底层输入流
DataOutputStream(OutputStream out)创建的数据输出流指向一个由参数out指定的底层输入流

常用方法:readBoolean(),readByte(),readChar(),readDouble(),readBFloat(),readInt(),readLong(),readShort(),readUnsignedByte(),readUnsignedShort(),readUTF()读取一个UTF字符串,skipBytes(int n)跳过给定数量的字节
writeBoolean(boolean v),writeBytes(String s),writeChars(String s),writeDouble(double v),writeFloat(float v),writeInt(int v),writeLong(long v),writeShort(int v),writeUTF(String s)

import java.io.*;

public class DataStream {
    public static void main(String[] args) throws IOException {
        File file = new File("E:\\Java\\myio\\a.txt");
        DataOutputStream dos  = new DataOutputStream(new FileOutputStream(file));
            dos.writeInt(100);
            dos.writeBoolean(true);
            dos.writeChars("abcdefabcdef");
            DataInputStream dis = new DataInputStream(new FileInputStream(file));
            System.out.println(dis.readInt());
            System.out.println(dis.readBoolean());
            dis.close();
            dos.close();
    }
}

在这里插入图片描述

  • 40
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值