Java输入输出流

Java输入输出流

在 Java 中所有数据都是使用流读写的。流是一组有序的数据序列,将数据从一个地方带到另一个地方。根据数据流向的不同,可以分为输入(Input)流和输出(Output)流两种。

Java系统流

  1. System.in 是 InputStream 类的一个对象,因此上述代码的 System.in.read() 方法实际是访问 InputStream 类定义的 read() 方法。该方法可以从键盘读取一个或多个字符。对于 System.out 输出流主要用于将指定内容输出到控制台。

  2. System.out 和 System.error 是 PrintStream 类的对象。因为 PrintStream 是一个从 OutputStream 派生的输出流,所以它还执行低级别的 write() 方法。因此,除了 print() 和 println() 方法可以完成控制台输出以外,System.out 还可以调用 write() 方法实现控制台输出。

  3. 在 Java 的开发中,乱码是一个比较常见的问题,乱码的产生就有一个原因,即输出内容的编码与接收内容的编码不一致。

Java File类(文件操作类)

File 类是 java.io 包中唯一代表磁盘文件本身的对象,也就是说,如果希望在程序中操作文件和目录,则都可以通过 File 类来完成。File 类定义了一些方法来操作文件,如新建、删除、重命名文件和目录等。
File 类不能访问文件内容本身,如果需要访问文件内容本身,则需要使用输入/输出流。

参考文献

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hHwWJtiT-1661583240307)(http://apidoc.jadinec.com//server/index.php?s=/api/attachment/visitFile&sign=e4e5f9635b1564fe9122410c5699dc73)]

File 类除了对文件的创建和删除外,还可以创建和删除目录。创建目录需要调用 mkdir() 方法,删除目录需要调用 delete() 方法。无论是创建还是删除目录都可以调用 exists() 方法判断目录是否存在。

public class Test04 {
    public static void main(String[] args) {
        String path = "C:/config/"; // 指定目录位置
        File f = new File(path); // 创建File对象
        if (f.exists()) {
            f.delete();
        }
        f.mkdir(); // 创建目录
    }
}
遍历文件

通过遍历目录可以在指定的目录中查找文件,或者显示所有的文件列表。File 类的 list() 方法提供了遍历目录功能

由于 list() 方法返回的字符数组中仅包含文件名称,因此为了获取文件类型和大小,必须先转换为 File 对象再调用其方法。


/**
 * @author Summer
 * @date 22/08/23
 */
public class FileTest1 {

        public static void main(String[] args) {
            // 建立File变量,并设定由f变量变数引用
            File f = new File("C:/");
            System.out.println("文件名称\t\t文件类型\t\t文件大小");
            System.out.println("===================================================");
            // 调用不带参数的list()方法,后面可以实现FilenameFilter接口,写过滤不同后缀名文件
            String fileList[] = f.list();
            // 遍历返回的字符数组
            for (int i = 0; i < fileList.length; i++) {
                System.out.print(fileList[i] + "\t\t");
                System.out.print((new File("C:/", fileList[i])).isFile() ? "文件" + "\t\t" : "文件夹" + "\t\t");
                System.out.println((new File("C:/", fileList[i])).length() + "字节");
            }
        }

}

在这里插入图片描述

过滤器

public static class ImageFilter implements FilenameFilter {
    // 实现 FilenameFilter 接口
    @Override
    public boolean accept(File dir, String name) {
        // 指定允许的文件类型
        return name.endsWith(".sys");
    }
}

而后将ImageFilter传入上面的方法即可

/**
 * @author Summer
 * @date 22/08/23
 */
public class FileTest1 {

        public static void main(String[] args) {
            // 建立File变量,并设定由f变量变数引用
            File f = new File("C:/");
            System.out.println("文件名称\t\t文件类型\t\t文件大小");
            System.out.println("===================================================");
            // 调用不带参数的list()方法
            String fileList[] = f.list(new ImageFilter());
            // 遍历返回的字符数组
            for (int i = 0; i < fileList.length; i++) {
                System.out.print(fileList[i] + "\t\t");
                System.out.print((new File("C:/", fileList[i])).isFile() ? "文件" + "\t\t" : "文件夹" + "\t\t");
                System.out.println((new File("C:/", fileList[i])).length() + "字节");
            }
        }


    public static class ImageFilter implements FilenameFilter {
        // 实现 FilenameFilter 接口
        @Override
        public boolean accept(File dir, String name) {
            // 指定允许的文件类型
            return name.endsWith(".sys");
        }
    }
}

运行结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PL7pnec5-1661583240308)(http://apidoc.jadinec.com//server/index.php?s=/api/attachment/visitFile&sign=c0e36b4f33c6e67d7e9650257d5195b2)]

Java字节流的使用:字节输入/输出流、文件输入/输出流、字节数组输入/输出流

InputStream 是 Java 所有字节输入流类的父类,OutputStream 是 Java 所有字节输出流类的父类,它们都是一个抽象类,因此继承它们的子类要重新定义父类中的抽象方法。

字节输入流

InputStream 类及其子类的对象表示字节输入流,InputStream 类的常用子类如下。

  • ByteArrayInputStream 类:将字节数组转换为字节输入流,从中读取字节。
  • FileInputStream 类:从文件中读取数据。
  • PipedInputStream 类:连接到一个 PipedOutputStream(管道输出流)。
  • SequenceInputStream 类:将多个字节输入流串联成一个字节输入流。
  • ObjectInputStream 类:将对象反序列化。

使用 InputStream 类的方法可以从流中读取一个或一批字节。

方法名作用
int read()从输入流中读取一个 8 位的字节,并把它转换为 0~255 的整数,最后返回整数。如果返回 -1,则表示已经到了输入流的末尾。为了提高 I/O 操作的效率,建议尽量使用 read() 方法的另外两种形式
int read(byte[] b)从输入流中读取若干字节,并把它们保存到参数 b 指定的字节数组中。 该方法返回读取的字节数。如果返回 -1,则表示已经到了输入流的末尾
int read(byte[] b, int off, int len)从输入流中读取若干字节,并把它们保存到参数 b 指定的字节数组中。其中,off 指定在字节数组中开始保存数据的起始下标;len 指定读取的字节数。该方法返回实际读取的字节数。如果返回 -1,则表示已经到了输入流的末尾
void close()关闭输入流。在读操作完成后,应该关闭输入流,系统将会释放与这个输入流相关的资源。注意,InputStream 类本身的 close() 方法不执行任何操作,但是它的许多子类重写了 close() 方法
int available()返回可以从输入流中读取的字节数

字节输出流

OutputStream 类及其子类的对象表示一个字节输出流。OutputStream 类的常用子类如下。

  • ByteArrayOutputStream 类:向内存缓冲区的字节数组中写数据。
  • FileOutputStream 类:向文件中写数据。
  • PipedOutputStream 类:连接到一个 PipedlntputStream(管道输入流)。
  • ObjectOutputStream 类:将对象序列化。
方法名作用
void write(int b)向输出流写入一个字节。这里的参数是 int 类型,但是它允许使用表达式,而不用强制转换成 byte 类型。为了提高 I/O 操作的效率,建议尽量使用write() 方法的另外两种形式
void write(byte[] b)把参数 b 指定的字节数组中的所有字节写到输出流中
void write(byte[] b,int off,int len)把参数 b 指定的字节数组中的若干字节写到输出流中。其中,off 指定字节数组中的起始下标,len 表示元素个数
void close()关闭输出流。写操作完成后,应该关闭输出流。系统将会释放与这个输出流相关的资源。注意,OutputStream 类本身的 close() 方法不执行任何操作,但是它的许多子类重写了 close() 方法
void flush()为了提高效率,在向输出流中写入数据时,数据一般会先保存到内存缓冲区中,只有当缓冲区中的数据达到一定程度时,缓冲区中的数据才会被写入输出流中。使用 flush() 方法则可以强制将缓冲区中的数据写入输出流,并清空缓冲区

字节数组输入流

ByteArrayInputStream 类可以从内存的字节数组中读取数据,该类有如下两种构造方法重载形式。

  • ByteArrayInputStream(byte[] buf):创建一个字节数组输入流,字节数组类型的数据源由参数 buf 指定。
  • ByteArrayInputStream(byte[] buf,int offse,int length):创建一个字节数组输入流,其中,参数 buf 指定字节数组类型的数据源,offset 指定在数组中开始读取数据的起始下标位置,length 指定读取的元素个数。

使用 ByteArrayInputStream 实现从一个字节数组中读取数据,再转换为 int 型进行输出。

public class ByteTest1 {
    public static void main(String[] args) {
        byte[] b = new byte[] { 1, -1, 25, -22, -5, 23 }; // 创建数组
        ByteArrayInputStream bais = new ByteArrayInputStream(b, 0, 6); // 创建字节数组输入流
        int i = bais.read(); // 从输入流中读取下一个字节,并转换成int型数据
        while (i != -1) { // 如果不返回-1,则表示没有到输入流的末尾
            System.out.println("原值=" + ( byte ) i + "\t\t\t转换为int类型=" + i);
            i = bais.read(); // 读取下一个
        }
    }
}

结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z746gL9C-1661583240309)(http://apidoc.jadinec.com//server/index.php?s=/api/attachment/visitFile&sign=9e241db4fd40a447aa519300f2502c6a)]

字节类型的 -1,二进制形式为 11111111,转换为 int 类型后的二进制形式为 00000000 00000000 0000000011111111,对应的十进制数为 255。

字节数组输出流

ByteArrayOutputStream 类可以向内存的字节数组中写入数据,该类的构造方法有如下两种重载形式。

  • ByteArrayOutputStream():创建一个字节数组输出流,输出流缓冲区的初始容量大小为 32 字节。
  • ByteArrayOutputStream(int size):创建一个字节数组输出流,输出流缓冲区的初始容量大小由参数 size 指定。

ByteArrayOutputStream 类中除了有前面介绍的字节输出流中的常用方法以外,还有如下两个方法

方法名作用
intsize()返回缓冲区中的当前字节数。
byte[] toByteArray()以字节数组的形式返回输出流中的当前内容。

文件输入流

在创建 FileInputStream 类的对象时,如果找不到指定的文件将拋出 FileNotFoundException 异常,该异常必须捕获或声明拋出。

FileInputStream 常用的构造方法主要有如下两种重载形式。

  • FileInputStream(File file):通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
  • FileInputStream(String name):通过打开一个到实际文件的链接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定
try {
    // 以File对象作为参数创建FileInputStream对象
    FileInputStream fis1 = new FileInputStream(new File("D:/mxl.txt"));
    // 以字符串值作为参数创建FilelnputStream对象
    FileInputStream fis2 = new FileInputStream("D:/mxl.txt");
} catch(FileNotFoundException e) {
    System.out.println("指定的文件找不到!");
}

文件输出流

FileOutputStream 类继承自 OutputStream 类,重写和实现了父类中的所有方法。FileOutputStream 类的对象表示一个文件字节输出流,可以向流中写入一个字节或一批字节。在创建 FileOutputStream 类的对象时,如果指定的文件不存在,则创建一个新文件;如果文件已存在,则清除原文件的内容重新写入。

FileOutputStream 类的构造方法主要有如下 4 种重载形式。

  • FileOutputStream(File file):创建一个文件输出流,参数 file 指定目标文件。
  • FileOutputStream(File file,boolean append):创建一个文件输出流,参数 file 指定目标文件,append 指定是否将数据添加到目标文件的内容末尾,如果为 true,则在末尾添加;如果为 false,则覆盖原有内容;其默认值为 false。
  • FileOutputStream(String name):创建一个文件输出流,参数 name 指定目标文件的文件路径信息。
  • FileOutputStream(String name,boolean append):创建一个文件输出流,参数 name 和 append 的含义同上。

注:目标文件可以不存在,但是路径必须存在。目标文件不能是文件夹路径(不能是已存在的目录),否则均会抛异常。


/**
 * @author Summer
 * @date 22/08/23
 */
@Slf4j
public class FileTest2 {
    public static void main(String[] args) throws IOException {
        //声明FileInputStream对象fis, FileOutputStream对象fos
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try{
            File srcFile = new File("D:/浏览器下载/kafka/src/main/java/com/summer/controller/KafkaController.java");
            // 实例化FileInputStream对象
            fis = new FileInputStream(srcFile);
            File targetFile = new File("D:/KafkaController.txt");
            // 实例化FileOutputStream对象
            fos = new FileOutputStream(targetFile);
            //每次读取1024字节
            byte [] bytes = new byte[1024];
            int i = fis.read(bytes);
            while (i != -1){
                fos.write(bytes,0,i);
                i = fis.read(bytes);
            }
            log.info("写入结束");

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        finally {
            try {
                //关闭流处理
                fis.close();
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1TlVmN2A-1661583240309)(http://apidoc.jadinec.com//server/index.php?s=/api/attachment/visitFile&sign=f320d0caf8e814674a3252be939f0aaa)]

写入成功
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4hZsE4mA-1661583240309)(http://apidoc.jadinec.com//server/index.php?s=/api/attachment/visitFile&sign=5923694ff857f95ff89811d807509728)]

Java字符流的使用:字符输入/输出流、字符文件和字符缓冲区的输入/输出流

字符输入流

Reader 类是所有字符流输入类的父类,该类定义了许多方法,这些方法对所有子类都是有效的。

Reader 类的常用子类如下

  • CharArrayReader 类:将字符数组转换为字符输入流,从中读取字符。
  • StringReader 类:将字符串转换为字符输入流,从中读取字符。
  • BufferedReader 类:为其他字符输入流提供读缓冲区。
  • PipedReader 类:连接到一个 PipedWriter。
  • InputStreamReader 类:将字节输入流转换为字符输入流,可以指定字符编码。
方法名作用
int read(char[] cbuf)从输入流中读取若干个字符,并把它们保存到参数 cbuf 指定的字符数组中。 该方法返回读取的字符数,如果返回 -1,则表示已经到了输入流的末尾
int read(char[] cbuf,int off,int len)从输入流中读取若干个字符,并把它们保存到参数 cbuf 指定的字符数组中。其中,off 指定在字符数组中开始保存数据的起始下标,len 指定读取的字符数。该方法返回实际读取的字符数,如果返回 -1,则表示已经到了输入流的末尾

字符输出流

Writer 类的常用子类如下。

  • CharArrayWriter 类:向内存缓冲区的字符数组写数据。
  • StringWriter 类:向内存缓冲区的字符串(StringBuffer)写数据。
  • BufferedWriter 类:为其他字符输出流提供写缓冲区。
  • PipedWriter 类:连接到一个 PipedReader。
  • OutputStreamReader 类:将字节输出流转换为字符输出流,可以指定字符编码。

其中也有很多write写入方法和上面类似, close()、flush()、void write(int c)、void write(char[] cbuf,int off,int len)等

方法名作用
append(char c)将参数 c 指定的字符添加到输出流中
append(charSequence esq)将参数 esq 指定的字符序列添加到输出流中
append(charSequence esq,int start,int end)将参数 esq 指定的字符序列的子序列添加到输出流中。其中,start 指定子序列的第一个字符的索引,end 指定子序列中最后一个字符后面的字符的索引,也就是说子序列的内容包含 start 索引处的字符,但不包括 end索引处的字符

字符文件输入流

  • FileReader(File file):在给定要读取数据的文件的情况下创建一个新的 FileReader 对象。其中,file 表示要从中读取数据的文件。
  • FileReader(String fileName):在给定从中读取数据的文件名的情况下创建一个新 FileReader 对象。其中,fileName 表示要从中读取数据的文件的名称,表示的是一个文件的完整路径。

字符文件输出流

  • FileWriter(File file):在指定 File 对象的情况下构造一个 FileWriter 对象。其中,file 表示要写入数据的 File 对象。
  • FileWriter(File file,boolean append):在指定 File 对象的情况下构造一个 FileWriter 对象,如果 append 的值为 true,则将字节写入文件末尾,而不是写入文件开始处。
  • FileWriter(String fileName):在指定文件名的情况下构造一个 FileWriter 对象。其中,fileName 表示要写入字符的文件名,表示的是完整路径。
  • FileWriter(String fileName,boolean append):在指定文件名以及要写入文件的位置的情况下构造 FileWriter 对象。其中,append 是一个 boolean 值,如果为 true,则将数据写入文件末尾,而不是文件开始处

字符缓冲区输入流

BufferedReader 类主要用于辅助其他字符输入流,它带有缓冲区,可以先将一批数据读到内存缓冲区。接下来的读操作就可以直接从缓冲区中获取数据,而不需要每次都从数据源读取数据并进行字符编码转换,这样就可以提高数据的读取效率。

BufferedReader 类的构造方法有如下两种重载形式。

  • BufferedReader(Reader in):创建一个 BufferedReader 来修饰参数 in 指定的字符输入流。
  • BufferedReader(Reader in,int size):创建一个 BufferedReader 来修饰参数 in 指定的字符输入流,参数 size 则用于指定缓冲区的大小,单位为字符。

提供了 readline() 方法,该方法读取该行全部内容,遇到 /r(回车) /n(换行) 或者 /r/n 则认为该行结束

InputStreamReader 用于将字节输入流转换为字符输入流,其中 OutputStreamWriter 用于将字节输出流转换为字符输出流。使用转换流可以在一定程度上避免乱码,还可以指定输入输出所使用的字符集。

字节---->字符

参考链接:Java字符流的使用:字符输入/输出流、字符文件和字符缓冲区的输入/输出流

Java 里的输入流与输出流是针对内存而言的,它是从内存中读写,而不是所说的显示与存盘。输入流与输出流都可以将内容从屏幕上显示出来。

不管从磁盘、网络还是键盘读,读到内存中就是 InputStream

不管写到磁盘、网络,或者写到屏幕,都是使用 OutputStream

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值