字节流
字节输入流 InputStream类及其子类
ByteArrayInputStream类 字节数组输入流
将字节数组转换为字节输入流,读取字节
String str = "hello,World!";
//定义一个byte数组接受字符串
byte[] bytes = str.getBytes();
//产生一个读取字符流数组对象
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
int count;
// 字节ASCII码 如果不存在返回-1
while ((count = byteArrayInputStream.read()) != -1) {
char ch = (char) count;
System.out.print(ch+" ");
}
byteArrayInputStream.close();
一次读取多个字节方法 需使用len 来表示实际读取长度 否则会出现 1234 4567 8967 因为读取是覆盖读取 4替换1 5替换2 依次类推
String str = "0123456789";
//将字符串转换为数组
byte[] bytes = str.getBytes();
//创建数组读取对象
ByteArrayInputStream by = new ByteArrayInputStream(bytes);
//定义一个数组读取数据
byte[] bytes1 = new byte[4];
int len;
//len表示实际读取长度将读取到的数据存入到bytes中
// while ((len = by.read(bytes1)) != -1) {
// String s1=new String(bytes1);
// System.out.print(s1);
}
System.out.println("============");
while ((len = by.read(bytes1)) != -1) {
String s = new String(bytes1, 0, len);
System.out.println(s);
}
FileInputStream 类 文件输入流
从文件中读取数据 文件输入流
File file = new File("D:\\a\\a\\a.txt");
FileInputStream fileInputStream = new FileInputStream(file);
//单字节读写方法
int in = fileInputStream.read();
//读取到的是相对应的ASCII码
System.out.println(in);
System.out.println((char) in);
//单字节循环读写
while (true) {
in = fileInputStream.read();
if (in == -1) {
break;
}
System.out.print((char) in);
}
//多字节循环读写 需要定义实际读取长度
byte[] bytes = new byte[4];
int len;
while (true) {
len = fileInputStream.read(bytes);
if (len == -1) {
break;
}
String ss = new String(bytes, 0, len);
System.out.print(ss);
}
fileInputStream.close();
}
字节输出流 OutputStream 类及其子类
ByteArrayOutputStream 类字节 数组输出流
向内存缓冲区的字节数组中写数据。
String str = "Hello,World!";
byte[] bytes = str.getBytes();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byteArrayOutputStream.write(bytes, 0, bytes.length);
String s=new String(bytes);
System.out.println(s);
byteArrayOutputStream.close();
FileOutputStream 类 文件输出流
向文件中写数据。
//单次写入数据
File file = new File("D:\\a\\a\\a.txt");
FileOutputStream out = new FileOutputStream(file);
byte[] bytes = "Hello,World!".getBytes();
//没有文件会创建文件 文件中有内容会替换掉文件中的内容
out.write(bytes);
out.close();
//循环给文件中写入内容 //文件输出流对象默认是覆盖原有元素 默认是false true表示在后面追加元素
FileOutputStream fileOutputStream = new FileOutputStream(file, true);
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("请输入内容");
String s = scanner.next();
if ("exit".equals(s)) {
break;
}
fileOutputStream.write(s.getBytes());
}
fileOutputStream.close();
带缓冲的字节流输入输出操作
缓冲流 缓冲区 (字符流读取自带缓冲效果 需要关闭或刷新)
带缓冲和不带缓冲的效果:
- 不带缓冲区输出时、java代码书写一个内容、输出一次内容
- 带缓冲区输出时、java代码书写完内容、只有进行刷新缓冲区或者关闭操作时(关闭自带一次刷新)才会输出内容
缓冲流,也叫高效流,是对字节流或者字符流的一种高效利用。缓冲流的原理是,在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,降低系统IO次数,从而提高读写的效率。
内存的读写效率比磁盘读写效率高 如果不加缓冲流会导致资源的浪费 读写速度较低
如快递员送快递 快递是内存 快递员就是磁盘 不加缓冲区就类似于快递小哥一个快递一个快递送、一个完了才能进行下一个、效率低,磁盘的IO操作比较频繁 加缓冲区就类似于快递小哥一次将一个地区快递放在快递车上一次送、效率高,磁盘IO请求量少。
缓冲流有什么好处么?为什么有了InputStream还需要BufferedInputStream呢?
BufferedInputStream、BufferedOutputStream是FilterInputStream、FilterOutputStream的子类,作为装饰器类,使用它们可以防止每次读取/发送数据时进行实际的写操作,代表着使用缓冲区。
我们有必要知道不带缓冲的操作,每读一个字节就要写入一个字节,由于涉及磁盘的IO操作相比内存的操作要慢很多,所以不带缓冲的流效率很低。带缓冲的流,可以一次读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多!
同时正因为它们实现了缓冲功能,所以要注意在使用BufferedOutputStream写完数据后,要调用flush()方法或close()方法,强行将缓冲区中的数据写出。否则可能无法写出数据。与之相似还BufferedReader和BufferedWriter两个类。
缓冲流相关类就是实现了缓冲功能的输入流/输出流。使用带缓冲的输入输出流,效率更高,速度更快。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MqTpAfVC-1680089144573)(C:\Users\27310\AppData\Roaming\Typora\typora-user-images\image-20230329182345737.png)]
带缓冲的输入输出代码实现
注意无论是读写都需要关闭缓冲区 否则代码效果无法实现
//带缓冲的写操作
File file = new File("D:\\a\\a\\a.txt");
FileOutputStream outputStream = new FileOutputStream(file, true);
BufferedOutputStream bf = new BufferedOutputStream(outputStream);
while (true) {
System.out.println("请输入");
String s = scanner.next();
if (s.equals("exit")) {
break;
}
bf.write(s.getBytes());
}
bf.close();
outputStream.close();
//带缓冲的读取、删除操作
File file = new File("D:\\a\\a\\b.txt");
FileInputStream in = new FileInputStream(file);
BufferedInputStream buf = new BufferedInputStream(in);
byte[] bytes = new byte[4];
while (true) {
int len = buf.read(bytes);
if (len == -1) {
break;
}
String s = new String(bytes, 0, len);
System.out.println(s);
}
file.deleteOnExit();
in.close();
buf.close();
字符流
同字节流方法相同 不过是对象名变了
字符流的读取自带缓冲效果 需要刷新或者关闭
// 字符流
public class DemoH {
// 字符流的读取
private static void a1() throws IOException {
File file = new File("D:\\a\\a\\a.txt");
Reader reader = new FileReader(file);
char ch = (char) reader.read();
System.out.println(ch);
}
//字符流的读取
public static void a2() throws IOException {
File file = new File("D:\\a\\a\\a.txt");
Reader reader = new FileReader(file);
char[] ch = new char[10];
int len;
while ((len = (reader.read(ch))) != -1) {
String s = new String(ch, 0, len);
System.out.println(s);
// System.out.print(ch);
}
reader.close();
}
// 带缓冲效果的字符流读取(只要涉及到文字的读取,推荐写法)
private static void a3() throws IOException {
File file = new File("D:\\a\\a\\a.txt");
Reader reader = new FileReader(file);
BufferedReader reader1 = new BufferedReader(reader);
while (true) {
String str = reader1.readLine();
if (str == null) {
break;
}
System.out.println(str);
}
}
// 字符流的写入
private static void b1() throws IOException {
File file = new File("D:\\a\\a\\b.txt");
Writer writer = new FileWriter(file, true);
String str = "Hello,World!";
// 其实字符流的写入也是自带缓冲效果
writer.write(str);
//需要刷新或者关闭
writer.close();
}
private static void b2() throws IOException {
File file = new File("D:\\a\\a\\b.txt");
Writer writer = new FileWriter(file);
BufferedWriter bufferedWriter = new BufferedWriter(writer);
bufferedWriter.write("你好,世界");
bufferedWriter.flush();
}
字节流和字符流的区别
字节流是处理类似于斤为单位的 字符流是处理类似于以个为单位的
读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
字符流:一次读入或读出是16位二进制。
字节流:一次读入或读出是8位二进制。
处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。设备上的数据无论是图片或者视频,文字,它们都以二进制存储的。二进制的最终都是以一个8位为数据单元进行体现,所以计算机中的最小数据单元就是字节。意味着,字节流可以处理设备上的所有数据,所以字节流一样可以处理字符数据。
符流是处理类似于以个为单位的
读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
字符流:一次读入或读出是16位二进制。
字节流:一次读入或读出是8位二进制。
处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。设备上的数据无论是图片或者视频,文字,它们都以二进制存储的。二进制的最终都是以一个8位为数据单元进行体现,所以计算机中的最小数据单元就是字节。意味着,字节流可以处理设备上的所有数据,所以字节流一样可以处理字符数据。