一.定义:(入门) 1.数据流: 数据流是一种用于输入输出基本数据类型的工具,它提供了将这些数据类型转换成字节流或字符流的方法,以方便进行输入输出操作。
在Java中的数据流指的是在处理输入、输出数据时通过内存缓冲区实现的读取和写入操作。Java中常用的数据流有字节流和字符流,可以根据具体需求选择使用。
2.数据流类型: 1.字节流:
字节流以字节(8位)为单位读取和写入数据。它通常用于处理二进制文件(如图像、音频、视频等),或者处理数据流中的原始字节数据。 在 Java 中,字节流主要由两个抽象基类组成:
InputStream(字节输入流):提供了读取数据的方法。 OutputStream(字节输出流):提供了写入数据的方法。 ▲注意:这两个类提供了一些基本方法,可以读写字节数组、单个字节或者跳过某些字节等操作。
2.字符流:
字符流以字符为单位读取和写入数据。它通常用于读写文本文件,或者处理字符数据流。 在 Java 中,字符流主要由两个类组成:
Reader(字符输入流):提供了读取数据的方法。 Writer(字符输出流):提供了写入数据的方法。 ▲注意:字符流底层仍然是使用字节流实现的,因此读取或写入字符时会涉及到编码和解码的过程。Java提供了一些标准的字符集(如UTF-8、GBK等)来支持不同的文本编码格式。
二.详细介绍:(升级) 1.字节流: 字节流是 Java 中用于读写二进制数据的一种流,它按照 8 位字节的方式传输数据。字节流主要用于处理二进制数据,例如图像、音频、视频等文件。
<1>常用的 InputStream 子类有:
FileInputStream:从文件中读取字节数据。 ByteArrayInputStream:从内存中的字节数组中读取数据。 ObjectInputStream:从对象序列化数据中读取对象。 代码示例:FileInputStre
import java.io.FileInputStream; import java.io.IOException; public class project//草稿类 { public static void main(String[] args)throws IOException { String path="D:\java\ProjectFile.txt";
try {
// 创建一个 FileInputStream 对象
FileInputStream fis = new FileInputStream(path);
// 定义一个字节数组,用于存储读取到的数据
byte[] buffer = new byte[1024];
// 定义一个变量,记录实际读取的字节数
int len;
// 循环读取数据
while ((len = fis.read(buffer)) != -1) {
// 将读取到的字节转换成字符串,并打印输出
System.out.print(new String(buffer, 0, len));
}
fis.close();// 关闭流
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
//文件里面的内容 解释:首先,我们创建了一个 FileInputStream 对象,并传入要读取的文件路径。然后定义了一个 byte 数组作为缓冲区,用于存储读取到的数据。接着进入循环进行读取,每次读取 buffer.length 长度的数据,并将实际读取到的字节数保存在 len 变量中。最后将读取到的字节转换成字符串并打印输出。
注意,在读取完成后,一定要记得关闭流,以释放相关的资源。如果没有关闭流,可能会导致资源泄露和程序崩溃。可以使用 try-with-resources 语句来自动关闭流,也可以在 finally 块中手动关闭流。
代码示例:ByteArrayInputStream
import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.Arrays; public class project { public static void main(String[] args) throws IOException { // 创建一个字节数组 byte[] bytes = {0x1, 0x2, 0x3, 0x4, 0x5};
// 将字节数组封装成为 ByteArrayInputStream 对象
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
// 定义一个字节型数组,用于存储读取到的数据
byte[] buffer = new byte[10];
// 从输入流中读取数据,并存储到缓冲区中,len记录了从输入流 bais 中读取的数据的字节数,以便程序在之后的处理中使用
int len = bais.read(buffer);
// 打印输出读取到的数据
System.out.println(Arrays.toString(buffer));
}
}
//输出:[1, 2, 3, 4, 5, 0, 0, 0, 0, 0] 首先,我们创建了一个字节数组,并将其封装成为一个 ByteArrayInputStream 对象。然后定义了一个 byte 数组作为缓冲区,用于存储从 ByteArrayInputStream 中读取到的数据。接着调用了 read() 方法从 ByteArrayInputStream 中读取数据,并将其存储到缓冲区中。最后打印输出了读取到的数据。
注意,在执行 read() 方法时,如果字节数组中没有数据可读,则该方法会返回 -1。因此,可以在循环中判断返回值是否为 -1,以确定是否已经读取到了字节数组的末尾。
使用 ByteArrayInputStream 从字节数组中读取数据时,不需要手动关闭流,因为它并没有打开任何底层资源。
代码示例:ObjectInputStream
import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream;
public class ObjectInputStreamExample
{
public static void main(String[] args)
{
// 创建一个 ObjectInputStream 对象
try (FileInputStream fis = new FileInputStream("person.dat");
ObjectInputStream ois = new ObjectInputStream(fis))
{
// 从文件中读取 Person 对象
Person person = (Person)ois.readObject();
System.out.println("Name: " + person.getName());
System.out.println("Age: " + person.getAge());
System.out.println("Gender: " + person.getGender());
}
catch (IOException | ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
// Person 类,为了演示方便,属性全部为公有 class Person implements java.io.Serializable { private static final long serialVersionUID = 1L; public String name; public int age; public String gender; public Person(String name, int age, String gender) { this.name = name; this.age = age; this.gender = gender; } public String getName() { return name; } public int getAge() { return age; } public String getGender() { return gender; } }
在这个示例中,我们创建了一个 ObjectInputStream 对象,用于从文件中读取保存的 Person 对象。然后使用 ois.readObject() 方法读取对象,并将其强制转换为 Person 类型。最后,将 Person 对象的属性值输出到控制台。
注意,我们需要为 Person 类实现 java.io.Serializable 接口才能将其保存到文件中并使用 ObjectInputStream 读取。此外,我们使用了 Java 7 中的 try-with-resources 语句来自动关闭输入流,并且使用了多重捕获语句处理可能出现的异常。
<2>常用的 OutputStream 子类有:
FileOutputStream:向文件中写入字节数据。 ByteArrayOutputStream:将字节数据写入到内存中的字节数组中。 ObjectOutputStream:将对象序列化数据写入到流中。 代码示例:FileOutputStream
import java.io.FileOutputStream; import java.io.IOException; public class FileOutputStreamExample { public static void main(String[] args) { // 创建一个字符串 String message = "Hello, World!";
try (FileOutputStream fos = new FileOutputStream("output.txt"))
{
// 将字符串转换为字节数组
byte[] data = message.getBytes();
// 将字节数组写入文件
fos.write(data);
System.out.println("数据已写入文件");
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
在这个示例中,我们创建了一个包含字符串 "Hello, World!" 的 message 变量。然后,我们使用 FileOutputStream 类创建了一个名为 "output.txt" 的文件输出流,并将 message 字符串转换为字节数组。最后,我们使用 fos.write(data) 方法将字节数组写入文件。需要注意的是,我们使用了 Java 7 中的 try-with-resources 语句来自动关闭输出流,并且使用了单重捕获语句处理可能出现的异常。
如果运行成功,程序将会在控制台输出 "数据已写入文件"。此时,在项目根目录下应该会出现一个名为 "output.txt" 的文件,其中包含了字符串 "Hello, World!" 的字节表示形式。
字节流在读写数据时通常需要使用缓冲区,这样可以提高性能。Java 中提供了BufferedInputStream 和 BufferedOutputStream 这两个字节流的缓冲区实现。
2.字符流: 字符流是 Java 中的一类处理字符数据的 I/O 流。与字节流不同,字符流的单位是char,它适合用于文本处理和国际化应用程序。Java 中的字符流继承自Reader和Writer两个抽象类,提供了一系列处理字符数据的方法。
java字符流主要包括以下几种:
FileReader 和 FileWriter:用于读取和写入字符文件。 BufferedReader 和 BufferWriter:提供了缓冲区功能,能够减少磁盘操作次数,提高效率。 InputStreamReader 和 OutputStreamWriter:在字节流和字符流之间进行转换,将字节流转换为字符流或将字符流转换为字节流。其中InputStreamReader将字节输入流转换为字符输入流OutputStreamWriter将字符输出流转换为字节输出流。 CharArrayReader 和 CharArrayWriter:用于读写字符数组。 StringReader 和StringWriter:用于读写字符串。 代码示例:FileReader
import java.io.FileReader; import java.io.IOException;
public class FileReaderExample
{
public static void main(String[] args)
{
try (FileReader reader = new FileReader("input.txt"))
{
int data = -1;
while ((data = reader.read()) != -1)
{
System.out.print((char) data);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
在这个示例中,我们使用 FileReader 类创建了一个字符输入流对象,用于读取名为 "input.txt" 的文件。然后,我们使用 read() 方法逐个字符地读取文件的内容,并将其转换为 char 类型,并输出到控制台。需要注意的是,在这个示例中,我们使用了 Java 7 中的 try-with-resources 语句来自动关闭输入流,并且使用了单重捕获语句处理可能出现的异常。