在完成对C语言的学习后,我最近开始了对C++和Java的学习,目前跟着视频学习了一些语法,也跟着敲了一些代码,有了一定的掌握程度。现在将跟着视频做的笔记进行整理。本篇博客是整理Java知识点的第二十三篇博客。
本篇博客介绍了Java的字节流。
本系列博客所有Java代码都使用IntelliJ IDEA编译运行,版本为2022.1。所用JDK版本为JDK11。
目录
字节流
IO流概述和分类
IO流是进行输入和输出的流。流是一种抽象概念,表示数据传输。IO流处理设备之间数据传输问题,用于文件复制,文件上传,文件下载等。
IO流按照数据流向分为进行读数据的输入流和进行写数据的输出流。按照数据类型分为字节流和字符流。
一般,如果用记事本能看懂内容,就用字符流,否则用字节流。如果不知道用哪种类型就用字节流。
字节流写数据
字节流的抽象基类InputStream表示字节输入流所有类的超类,抽象基类OutputStream是字节输出流所有类的超类。子类名称以父类名作为子类名的后缀。
FileOutputStream用于将数据写入File。使用此类需要导包,import java.io.FileInputStream。
FileOutputStream(String name)用于创建文件输出流,将数据写入name文件。
写数据要先创建流对象,然后调用写数据方法,最后释放资源。close方法关闭流并释放资源。
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class writetest1 {
public static void main(String[] args) throws IOException {
FileOutputStream f = new FileOutputStream("test.txt");
f.write(48);
f.write(65);
f.write(97);
f.close();
}
}
程序创建了一个FileOutputStream流,并进行输出。程序无输出,test.txt的内容是:
0Aa
字节流写数据的方式
void write(int b)将b写入输出流,这里的b是字符的ASCII码值,一次写一个数据。
void write(byte[] b)将b.length字节写入输出流,一次写入整个数组数据,数值是ASCII码值。
void write(byte[] b,int off,int len)从b的off位置开始,将len个字节写入输出流,数值是ASCII码值。
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class writetest2 {
public static void main(String[] args) throws IOException {
FileOutputStream f = new FileOutputStream("test.txt");
f.write(66);
f.write(98);
f.write(10);
byte[] by = {99,100,101,102};
f.write(by);
byte[] bys = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".getBytes();
f.write(bys,11,3);
f.close();
}
}
程序无输出,test.txt的内容是:
Bb
cdefLMN
覆盖了原来的内容(即上次输出)。
String类的getBytes()方法将字符串内容转换为byte数组。
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class writetest3 {
public static void main(String[] args) throws IOException {
FileOutputStream f = new FileOutputStream("test.txt");
int i;
for(i = 0; i < 10;i += 1){
f.write("Hello".getBytes());
f.write("\n".getBytes());
}
f.close();
}
}
程序无输出,test.txt的内容是:
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
共10行Hello。覆盖了原有数据。
字节流追加数据
public FileOutputStream(String name,boolean append)创建文件输出流,写入name文件。如果append为true,就写入文件末尾。
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class writetest4 {
public static void main(String[] args) throws IOException {
FileOutputStream f = new FileOutputStream("test.txt",true);
f.write("Hello Java".getBytes());
f.close();
}
}
程序无输出。test.txt的内容是:
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello Java
原来的内容没有被覆盖,末尾增加了Hello Java。
字节流写数据加异常处理
异常处理时,finally块执行所有清除操作。被finally控制的语句一定执行。格式是:
try{
可能出现异常的代码
}catch(异常类名,变量名){
异常的处理代码
}finally{
所有清除操作
}
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class writetest5 {
public static void main(String[] args){
FileOutputStream f = null;
try {
f = new FileOutputStream("E:\\test");
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
try {
f.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
本人的电脑没有E盘,因此,程序的输出是:
java.io.FileNotFoundException: E:\test (系统找不到指定的路径。)
at java.base/java.io.FileOutputStream.open0(Native Method)
at java.base/java.io.FileOutputStream.open(FileOutputStream.java:298)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:237)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:126)
at writetest5.main(writetest5.java:9)
Exception in thread "main" java.lang.NullPointerException
at writetest5.main(writetest5.java:14)
字节流读数据
FileInputStream(String name)创建一个文件输入流,指向文件的名字是name。使用FileInputStream需要导包,import java.io.FileInputStream。
读数据首先创建输入流对象,然后用读数据方法,最后close释放资源。
read()方法向后读取一个字节,并返回其ASCII码值,结果是int类型,可以强制类型转换为char型。读到文件末尾返回-1。
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class readtest1 {
public static void main(String[] args) throws IOException {
FileInputStream f = new FileInputStream("test.txt");
int ch;
while((ch = f.read()) != -1){
System.out.print((char)ch);
}
f.close();
}
}
程序使用循环,只要不读到结尾就一直读取,读取后立即输出。程序的输出是:
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello Java
字节流复制文本文件
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class readwrite {
public static void main(String[] args) throws IOException {
int ch;
FileInputStream fis = new FileInputStream("test1.txt");
FileOutputStream fos = new FileOutputStream("test2.txt");
while((ch = fis.read()) != -1){
fos.write(ch);
}
fis.close();
fos.close();
}
}
程序创建了FileInputStream流对象fis和FileOutputStream流对象fos。采用循环,用int类型变量ch接受fis读取的内容,只要fis没有读到结尾,fos就将ch进行写入。结束后关闭fis和fos。
程序无输出。执行结束后test1和test2都是下面内容:
20220818
Hello Java
IO
这是预先准备的内容。
字节流读数据
int read(byte[] b)最多读取b.length个长度,并将读入的长度返回,读完后返回-1。
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class readtest2 {
public static void main(String[] args) throws IOException {
FileInputStream f = new FileInputStream("test1.txt");
byte[] bytes = new byte[1024];
int len;
while((len = f.read(bytes)) != -1){
System.out.println(new String(bytes,0,len));
}
f.close();
}
}
程序的输出是:
20220818
Hello Java
IO
字节流复制图片
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class readwritetest1 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("D:\\university\\13-2\\summary.png");
FileOutputStream fos = new FileOutputStream("D:\\university\\summary.png");
byte[] bytes = new byte[1024];
int len;
while((len = fis.read(bytes)) != -1){
fos.write(bytes,0,len);
}
fis.close();
fos.close();
}
}
同样使用两个流,一个读一个写。读入后就将数据写出。程序无输出。复制了图片,此处不再展示。
字节缓冲流
BufferedOutputStream实现缓冲输出流,使得应用程序可以向底层输出流写入数据,不必因为写入的每个字节导致底层系统的调用。构造方法是:
BufferedOutputStream(OutputStream out)
使用此类需要导包,import java.io.BufferedOutputStream
BufferedInputStream实现缓冲输入流,此流创建一个内部缓冲区数组,从流中读取内容时,内部缓冲区根据需要从包含的输入流重新填充。构造方法是:
BufferedInputStream(InputStream in)
字节缓冲流只提供缓冲区,真正的读写还需要基本的字节流对象进行操作。
import java.io.*;
public class buffertest1 {
public static void main(String[] args) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("test1.txt"));
byte[] bytes = new byte[1024];
int len;
while((len = bis.read(bytes)) != -1){
System.out.println(new String(bytes, 0, len));
}
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("test1.txt"));
byte[] bytest = new byte[1024];
bytest = "20220717 mission accomplished".getBytes();
bos.write(bytest);
bis.close();
bos.close();
}
}
程序首先利用缓冲输入流读取数据,并将读入的数据进行输入。随后通过缓冲输出流进行输出。
程序的输出是:
20220818
Hello Java
IO
同时向文件输出的内容也成功输出。