Java字节流battle字符流

目录

Java字节流(Byte Stream)

FileInputStream和FileOutputStream

Java字符流(Character Stream)

FileReader和FileWriter

如何在使用是区分什么时候用输出什么时候用输入

Write方法

close方法

Java中的close方法本身抛出的异常是什么

FileOutputStream(文件输出流)

FileInputStream(文件输入流)

FileInputStream文件输入流,参数中的文件不存在时会直接抛出异常不会尝试创建新文件;

read方法和Write方法


        

Java中的流(stream)是数据传输的一种方式,可以将输入或输出数据从一个地方传递到另一个地方。Java的I/O库提供了两种类型的流:字节流和字符流。

Java字节流(Byte Stream)

        Java字节流以字节为单位进行读写操作,是处理所有类型的二进制数据的推荐方式。它们在I/O基础设施中使用最广泛,因为它们处理原始的二进制数据。

FileInputStream和FileOutputStream

        Java中最基本的字节流类是FileInputStream和FileOutputStream。文件输入流(FileInputStream)用于从文件中读取数据,而文件输出流(FileOutputStream)用于向文件中写入数据。这两个类可以用来移动二进制数据,比如图像和声音等。

  • 优点

    • 字节流对于任何类型的文件都可以使用,包括文本和二进制文件。
    • 字节流通常比字符流更快,在处理大量数据时性能更好。
  • 缺点

    • 不适合处理文本数据,可能会导致编码问题。
    • 在处理文本文件时需要手动进行编解码。
  • 使用案例

    • 图片和视频的读写操作
    • 数据压缩和加密

Java字符流(Character Stream)

        Java字符流以字符为单位进行读写操作,是处理文本数据的首选方式。它们使用Unicode编码并在内存中使用16位字符集表示。

FileReader和FileWriter

        Java中最基本的字符流类是FileReader和FileWriter。文件读取器(FileReader)用于从文本文件中读取数据,而文件写入器(FileWriter)用于向文本文件中写入数据。

  • 优点

    • 处理文本文件时,字符流通常比字节流更方便。
    • 自动进行编解码,无需手动进行转换。
  • 缺点

    • 在处理二进制数据时不如字节流效率高。
    • 不能处理所有类型的文件,比如图片或视频等。
  • 使用案例

    • 文本文件的读写操作
    • 网络传输中的文本数据的读写操作

        总的来说,字节流适合处理任何类型的文件,但在处理文本数据时需要手动进行编解码。字符流适合处理文本文件,并且自动进行编解码。因此,根据具体的使用场景和需求选择合适的流非常重要。

如何在使用是区分什么时候用输出什么时候用输入

这个问题困扰我很长时间啊,关键时刻就会搞混,为此痛书下文:(以文件的读写流举例)

FileInputStream:文件输入流,从文件中读出数据,方法read();

FileOutputStream:文件输出流,向文件中写入数据,方法write();

记住以上两句话,不要去问为什么,记住就好了,等你彻底记住了在问为什么;

Write方法

        这里为什么把这个方法单独拿出来呢?因为这个方法本身会抛出受检异常,你必须在编译之前对他做出处理;

在Java中,write()方法用于将数据写入输出流。这个方法本身可能会抛出多种异常,包括以下几种:

  1. IOException
    • 描述:当发生I/O错误(如文件系统错误或网络错误)时抛出。
  2. NullPointerException
    • 描述:当参数为null时抛出。
  3. IndexOutOfBoundsException
    • 描述:当指定的偏移量和长度超出了有效数据范围时抛出。

        需要注意的是,如果使用带缓冲区的流对象(例如BufferedOutputStream),则调用write()方法不一定会触发I/O操作。相反,它会将数据存储在缓冲区中,并且只有当缓冲区已满或手动刷新缓冲区时才会执行实际的I/O操作。在这种情况下,如果发生I/O错误,则可能会在刷新缓冲区时抛出异常,而不是在调用write()方法时抛出异常。

close方法

为了加深联想记忆,我们在单独把close方法拿出来,同样它本身也会抛出异常我之前一直以为他的异常只是null异常(就是流对象值为null时,仍旧调用close时才抛出异常),但实则不然,以下代码为例(注意下面代码有错误):

if(fin!=null){
    fin.close();
 }       

        因为我单独写出 fin.close()时会报异常,所以我在fin.close()外面加入了if判断,之后他仍旧会抛出异常,之后我就发觉不对,重新查了下资料得:

Java中的close方法本身抛出的异常是什么

        在Java中,close()方法是用于关闭流的方法。当调用close()方法时,可能会发生异常并抛出异常。具体来说,close()方法本身可能会抛出IOException异常。

        IOException是Java中的一个checked exception(受检异常),表示在输入/输出过程中发生了一般性错误。因为close()方法涉及到I/O操作,所以它可能会在关闭流的过程中抛出IOException异常。例如,在使用文件输入/输出流时,如果在关闭流之前尚未完成读取/写入操作,则可能会出现IOException异常。同样,在使用网络套接字时,如果在从套接字中读取或写入数据时发生错误,则可能在关闭套接字之前出现IOException异常。

        因此,当使用close()方法时,需要使用try-catch语句来捕获可能抛出的IOException异常,并进行适当的异常处理。通常情况下,在finally块中调用close()方法是良好的编程习惯,以确保资源得以正确释放。例如:

FileInputStream in = null;
try {
    in = new FileInputStream("example.txt");
    // ...
} catch (IOException e) {
    // 处理异常
} finally {
    if (in != null) {
        try {
            in.close();
        } catch (IOException e) {
            // 处理异常
        }
    }
}

FileOutputStream(文件输出流)

        然后我们来谈一谈FileOutputStream,这个流对象很牛逼啊,有些不为人知的操作:

在Java中,FileOutputStream有两种构造函数来创建一个文件输出流对象,这两个构造函数的参数如下:

  1. FileOutputStream(File file)

    • 参数类型:File
    • 描述:创建一个将数据写入指定文件的文件输出流对象。如果指定的文件不存在,则会尝试创建该文件。
  2. FileOutputStream(String name, boolean append)

    • 参数类型:
      • String name: 文件名(包括其路径)。
      • boolean append: 如果为true,则此文件输出流将被打开以进行追加写入;否则文件将被覆盖。
    • 描述:创建一个将数据写入指定文件的文件输出流对象。如果指定的文件不存在,并且append参数为false,则会尝试创建该文件。

        需要注意的是,如果使用第二种构造函数来创建FileOutputStream对象,还可以使用另一种重载形式的构造函数来设置缓冲区大小。例如:

FileOutputStream fos = new FileOutputStream("example.txt", true);
BufferedOutputStream bos = new BufferedOutputStream(fos, 4096);

        上述代码中,BufferedOutputStream的构造函数接收一个FileOutputStream对象和一个整数参数作为输入。该整数表示缓冲区的大小。通过使用带有缓冲区大小参数的构造函数,可以提高输出性能并减少系统调用次数

FileInputStream(文件输入流)

相对于输出流,输入流比较简单:在Java中,FileInputStream有三个构造函数用于创建一个文件输入流对象,这三个构造函数的参数如下:

  1. FileInputStream(File file)

    • 参数类型:File
    • 描述:创建一个从指定文件读取数据的文件输入流对象
  2. FileInputStream(String name)

    • 参数类型:String
    • 描述:创建一个从指定路径名(包括文件名)读取数据的文件输入流对象
  3. FileInputStream(FileDescriptor fdObj)

    • 参数类型:FileDescriptor
    • 描述:创建一个从指定文件描述符读取数据的文件输入流对象

需要注意的是,FileInputStream类没有设置缓冲区的构造函数。如果需要使用带有缓冲区的输入流对象,则可以将FileInputStreamBufferedInputStream一起使用。例如:

FileInputStream fis = new FileInputStream("example.txt");
BufferedInputStream bis = new BufferedInputStream(fis, 4096);

        上述代码中,BufferedInputStream构造函数接收一个FileInputStream对象和一个整数参数作为输入。该整数表示缓冲区的大小。通过使用带有缓冲区大小参数的构造函数,可以提高输入性能并减少系统调用次数。

FileInputStream文件输入流,参数中的文件不存在时会直接抛出异常不会尝试创建新文件;

        在Java中,FileInputStream的构造函数用于创建一个从文件读取数据的输入流对象。如果指定的文件不存在,则会抛出FileNotFoundException异常,而不是尝试创建该文件。

因此,如果要使用FileInputStream从文件读取数据,并且不确定文件是否存在,可以通过以下步骤来避免出现异常:

  1. 使用Java中的File类或其他文件操作API来检查文件是否存在。
  2. 如果文件存在,则使用FileInputStream构造函数来创建输入流对象;否则,进行相应的错误处理。

例如,下面的代码演示了如何检查文件是否存在并使用FileInputStream从文件读取数据:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamExample {

    public static void main(String[] args) {
        File file = new File("example.txt");
        if (file.exists()) {
            try {
                FileInputStream fis = new FileInputStream(file);
                // 从输入流中读取数据...
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            System.err.println("File not found: " + file.getAbsolutePath());
        }
    }

}

        上述代码中,首先检查文件是否存在,如果存在则使用FileInputStream构造函数创建输入流对象并从中读取数据。如果文件不存在,则输出错误信息并终止程序。

        需要注意的是,FileInputStream只能用于读取已存在的文件,并不能用于创建新的文件。如果需要创建新的文件,应该使用FileOutputStream(或其他文件操作API)来创建输出流并写入数据。

read方法和Write方法

这个部分里面我们主要强调的是,read和write方法的参数以及返回值,你可以从下图中看出,

  • 返回值

    • int:返回实际读取的字节数。如果已经到达文件的末尾,则返回-1。在实际应用中我们通过返回的值来判断是否读取完数据;
  • 参数
  • 空参表示一次读出一个字节数据,然后其他上面都有;

 

 对于Write方法,他没有返回值,主要是参数,可以一次写入一个字节,或者一个字节数组的数据;

 fou = new FileOutputStream("./2.txt");
 fin = new FileInputStream("");
 String str = new String("qwertyuiop");
 fou.write(2);//write方法本身会抛出异常;一次写入一个字节
 fou.write(str.getBytes());//一次写入一个字节数组

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值