概述
目录
- 字节流
- 1. 输入流 InputStream
- a. InputStream 的常用方法
- b. FileInputStream 类
- i. 读取字节
- ii. 读取字节数组
- c. FileInputStream 类读取并显示文件
- 2. 输出流 OutputStream
- a. OutputStream 的常用方法
- b. FileOutputStream 类
- i. 写入字节
- ii. 写入字节数组
- iii. 写入指定长度数组
- iv. 数据追加续写
- v. 写出换行
- c. FileOutputStream 类写入数据
- 3. 综合应用
- a. 写入并读出数据
- b. 图片复制
字节流
- 字节流(byte stream)类以字节为单位处理数据;
- 字节流不会对数据进行任何转换,因此可以用来处理二进制数据;
- 一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都是一个一个的字节,那么传输时一样如此,所以,字节流可以传输任意文件数据。注意,在操作流的时候,无论使用什么样的流对象,底层传输的始终为二进制数据;
- 字节输入流 FileInputStream 和字节输出流 FileOutputStream 分别是抽象类输入流 InputStream 和输出流 OutputStream 的子类,InputStream 和 OutputStream 主要用于操作系统的输入输出,管理声音、键盘输入等功能;
1. 输入流 InputStream
- 字节输入流的作用是从数据输入源(例如磁盘、网络等)获取字节数据到应用程序(内存)中;
- InputStream 是一个定义了 Java 流式字节输入模式的抽象类,该类的所有方法在出错时都会引发一个 IOException 异常;
a. InputStream 的常用方法
类型 | 方法 | 说明 |
---|---|---|
int | available() | 返回当前可读的输入字节数 |
void | close() | 关闭输入流,关闭后再读取会抛出 IOException 异常 |
void | mark(int numBytes) | 在输入流的当前点设置一个标记,该流在读取 numBytes 个字节前都保持有效 |
boolean | markSupported() | 如果调用的流支持 mark()/reset() 就返回 true |
int | read() | 如果下一个字节可读则返回一个整型,遇到文件结尾时返回 -1 |
int | read(byte buffer[]) | 尝试读取 buffer.length 个字节到 buffer 中,返回实际读取的字节数,遇到文件结尾时返回 -1 |
int | read(byte buffer[], int offset, int numBytes) | 尝试读取 buffer[offset] 开始的 numBytes 个字节,返回实际读取的字节数,遇到文件结尾时返回 -1 |
void | reset() | 重新设置输入指针到先前设置的标志处 |
long | skip(long numBytes) | 忽略 numBytes 个输入字节,返回实际忽略的字节数 |
b. FileInputStream 类
构造方法 | 说明 |
---|---|
FileInputStream(String filepath) | 文件的绝对路径,比较常用 |
FileInputStream(File fileObj) | fileObj 是描述该文件的 File 对象,允许在把文件赋给输入流之前用 File 方法更进一步检查文件 |
i. 读取字节
- read 方法,每次可以读取一个字节的数据,提升为 int 类型,读取到文件末尾,返回 -1;
import java.io.FileInputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
//使用文件名称创建流对象
FileInputStream fis = new FileInputStream("C:\Users\80626\Desktop\1.txt");
//文件内容: abcde
//定义变量,保存数据
int b;
//循环读取
while ((b = fis.read()) != -1) {
System.out.println((char) b);
}
//关闭资源
fis.close();
}
}
/*
输出
a
b
c
d
e
*/
- 虽然读取了一个字节,但是会自动提升为 int 类型;
ii. 读取字节数组
- read(byte[] b),每次读取b的长度个字节到数组中,返回读取到的有效字节个数,读取到末尾时,返回 -1;
import java.io.FileInputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
//使用文件名称创建流对象.
FileInputStream fis = new FileInputStream("C:\Users\80626\Desktop\1.txt");
//文件中为abcde
//定义变量,作为有效个数
int len;
//定义字节数组,作为装字节数据的容器
byte[] b = new byte[2];
//循环读取
while ((len = fis.read(b)) != -1) {
//每次读取后,把数组变成字符串打印
System.out.println(new String(b));
}
//关闭资源
fis.close();
}
}
/*
输出
ab
cd
ed
*/
- 使用数组读取,每次读取多个字节,减少了系统间的IO操作次数,从而提高了读写的效率,建议开发中使用;
- 错误数据 d ,是由于最后一次读取时,只读取一个字节 e ,数组中,上次读取的数据没有被完全替换,所以要通
过 len ,获取有效的字节:
import java.io.FileInputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
//使用文件名称创建流对象.
FileInputStream fis = new FileInputStream("C:\Users\80626\Desktop\1.txt");
//文件中为abcde
//定义变量,作为有效个数
int len;
//定义字节数组,作为装字节数据的容器
byte[] b = new byte[2];
//循环读取
while ((len = fis.read(b)) != -1) {
//每次读取后,把数组的有效字节部分,变成字符串打印
System.out.println(new String(b, 0, len));// len 每次读取的有效字节个数
}
//关闭资源
fis.close();
}
}
/*
输出
ab
cd
e
*/
c. FileInputStream 类读取并显示文件
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
byte[] b = new byte[1024];//设置字节缓冲区
int n = -1;
System.out.println("请输入要读取的文件名:(例如:d:\hello.txt)");
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();//获取要读取的文件名
try {
FileInputStream in = new FileInputStream(str);//创建字节输入流
while ((n = in.read(b, 0, 1024)) != -1) {//读取文件内容到缓冲区,并显示
String s = new String(b, 0, n);
System.out.println(s);
}
in.close();//读取文件结束,关闭文件
} catch (IOException e) {
System.out.println("文件读取失败");
}
}
}
/*
输出
请输入要读取的文件名:(例如:d:hello.txt)
C:Users80626Desktop1.txt
ssssaaa手动阀阿斯顿发
*/
2. 输出流 OutputStream
- 字节输出流的作用是将字节数据从应用程序(内存)中传送到输出目标,如外部设备、 网络等;
- OutputStream 是一个定义了 Java 流式字节输出模式的抽象类,该类的所有方法都会返回一个 void 值,并在出错时都会引发一个 IOException 异常;
a. OutputStream 的常用方法
类型 | 方法 | 说明 |
---|---|---|
void | close() | 关闭输出流并释放与此流相关联的任何系统资源,关闭后再操作会抛出 IOException 异常 |
void | flush() | 刷新输出缓冲区,并强制任何缓冲的输出字节被写出 |
void | write(int b) | 向输出流写入单个字节,参数是个整型数 |
void | write(byte buffer[]) | 向一个输出流写一个完整的字节数组 |
void | write(byte buffer[], int offset, int numBytes) | 写数组 buffer 以 buffer[offset] 为起点的 numBytes 个字节区域内的内容 |
abstract void | write(int b) | 将指定的字节输出流 |
- close() 方法,当完成流的操作时,必须调用此方法,释放系统资源;
b. FileOutputStream 类
构造方法 | 说明 |
---|---|
FileOutputStream(String filepath) | 文件的绝对路径 |
FileOutputStream(File fileObj) | fileObj 是描述该文件的 File 对象 |
FileOutputStream(String filePath, boolean append) | 如果 append 为 true,文件则以设置搜索路径模式打开 |
- FileOutputStream 的创建不依赖于文件是否存在,它会在打开输出文件后就创建它,如果尝试打开一个只读文件,则会引发 IOException 异常;
- 在完成操作过程中,系统会将数据暂存到缓冲区,缓冲区满了后再一次性写入到输出流中,执行 close() 方法时,不管缓冲区是否已满,都会把其中的数据写到输出流;
i. 写入字节
- write(int b) 方法,每次可以写出一个字节数据;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
//使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("C:\Users\80626\Desktop\1.txt");
//写出数据
fos.write(97); //写出第1个字节
fos.write(98); //写出第2个字节
fos.write(99); //写出第3个字节
//关闭资源
fos.close();
}
}
/*
文件
abc
*/
- 虽然参数为 int 类型四个字节,但是只会保留一个字节的信息写出;
ii. 写入字节数组
- write(byte[] b),每次可以写出数组中的数据;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
//使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("C:\Users\80626\Desktop\1.txt");
//字符串转换为字节数组
byte[] b = "abcde".getBytes();
//写出从索引2开始,2个字节。索引2是c,两个字节,也就是cd。
fos.write(b, 2, 2);
//关闭资源
fos.close();
}
}
/*
文件
cd
*/
iii. 写入指定长度数组
- write(byte[] b, int off, int len) ,每次写出从 off 索引开始,len 个字节;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
//使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("fos.txt");
//字符串转换为字节数组
byte[] b = "abcde".getBytes();
//写出从索引2开始,2个字节。索引2是c,两个字节,也就是cd。
fos.write(b, 2, 2);
//关闭资源
fos.close();
}
}
/*
文件
cd
*/
iv. 数据追加续写
- 以上的演示,每次程序运行,创建输出流对象,都会清空目标文件中的数据;
- 下列两个构造方法,参数中都需要传入一个 boolean 类型的值, true 表示追加数据, false 表示清空原有数据;
public FileOutputStream(File file, boolean append)
创建文件输出流以写入由指定的 File 对象表示的文件;public FileOutputStream(String name, boolean append)
创建文件输出流以指定的名称写入文件;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
//使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("fos.txt",true);
//字符串转换为字节数组
byte[] b = "abcde".getBytes();
//写出从索引2开始,2个字节。索引2是c,两个字节,也就是cd。
fos.write(b);
//关闭资源
fos.close();
}
}
/*
文件操作前:cd
文件操作后:cdabcde
*/
v. 写出换行
- Windows 系统里,换行符号是 rn;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("fos.txt");
// 定义字节数组
byte[] words = {97, 98, 99, 100, 101};
// 遍历数组
for (int i = 0; i < words.length; i++) {
// 写出一个字节
fos.write(words[i]);
// 写出一个换行, 换行符号转成数组写出
fos.write("rn".getBytes());
}
// 关闭资源
fos.close();
}
}
/*
文件
a
b
c
d
e
*/
回车符 r 和换行符 n :
- 回车符:回到一行的开头(return);
- 换行符:下一行(newline);
系统中的换行:
- Windows 系统里,每行结尾是 回车 + 换行 ,即 rn ;
- UnixLinux 系统里,每行结尾只有换行 ,即 n ;
- Mac 系统里,每行结尾是 回车 ,即 r,从 Mac OS X 开始与 Linux 统一
c. FileOutputStream 类写入数据
- 第二次操作采用追加方式完成:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
String content;//待输出字符串
byte[] b;//输出字节流
FileOutputStream out;//文件输出流
Scanner scanner = new Scanner(System.in);
System.out.println("请输入文件名:(例如,d:\hello.txt)");
String filename = scanner.nextLine();
File file = new File(filename);//创建文件对象
if (!file.exists()) {//判断文件是否存在
System.out.println("文件不存在,是否创建?(y/n)");
String f = scanner.nextLine();
if (f.equalsIgnoreCase("n"))
System.exit(0);//不创建,退出
else {
try {
file.createNewFile();//创建新文件
} catch (IOException e) {
System.out.println("创建失败");
System.exit(0);
}
}
}
try {//向文件中写内容
content = "Hello";
b = content.getBytes();
out = new FileOutputStream(file);//建立文件输出流
out.write(b);//完成写操作
out.close();//关闭输出流
System.out.println("文件写操作成功!");
} catch (IOException e) {
e.getMessage();
}
try {//向文件中追加内容
System.out.println("请输入追加的内容:");
content = scanner.nextLine();
b = content.getBytes();
out = new FileOutputStream(file, true);//创建可追加内容的输出流
out.write(b);//完成追加写操作
out.close();//关闭输出流
System.out.println("文件追加写操作成功!");
scanner.close();
} catch (IOException e) {
e.getMessage();
}
}
}
/*
输出
请输入文件名:(例如,d:hello.txt)
C:Users80626Desktop1.txt
文件写操作成功!
请输入追加的内容:
fsfad
文件追加写操作成功!
文件
Hellofsfad
*/
3. 综合应用
a. 写入并读出数据
import java.io.*;
public class Test {
public static void main(String args[]) {
File f = new File("C:\Users\80626\Desktop\1.txt");
OutputStream out = null;
try {
out = new FileOutputStream(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// 将字符串转成字节数组
byte b[] = "Hello World!!!".getBytes();
try {
// 将byte数组写入到文件之中
out.write(b);
} catch (IOException e1) {
e1.printStackTrace();
}
try {
out.close();
} catch (IOException e2) {
e2.printStackTrace();
}
// 以下为读文件操作
InputStream in = null;
try {
in = new FileInputStream(f);
} catch (FileNotFoundException e3) {
e3.printStackTrace();
}
// 开辟一个空间用于接收文件读进来的数据
byte b1[] = new byte[1024];
int i = 0;
try {
// 将b1的引用传递到read()方法之中,同时此方法返回读入数据的个数
i = in.read(b1);
} catch (IOException e4) {
e4.printStackTrace();
}
try {
in.close();
} catch (IOException e5) {
e5.printStackTrace();
}
//将byte数组转换为字符串输出
System.out.println(new String(b1, 0, i));
}
}
/*
输出
Hello World!!!
文件
Hello World!!!
*/
b. 图片复制
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
// 1.创建流对象
// 1.1 指定数据源
FileInputStream fis = new FileInputStream("C:\Users\80626\Desktop\test.jpg");
// 1.2 指定目的地
FileOutputStream fos = new FileOutputStream("C:\Users\80626\Desktop\test_copy.jpg");
// 2.读写数据
// 2.1 定义数组
byte[] b = new byte[1024];//一次拿1024个字节,即1KB,上限与CPU高速缓存的处理能力有关,一般不要超过8KB
// 2.2 定义长度
int len;
// 2.3 循环读取
while ((len = fis.read(b)) != -1) {//避免了代码冗余
// 2.4 写出数据
fos.write(b, 0, len);
}
// 3.关闭资源
fos.close();
fis.close();
}
}
- 流的关闭原则:先开后关,后开先关,调整顺序无影响;
最后
以上就是愤怒仙人掌为你收集整理的Java byte stream 字节流字节流的全部内容,希望文章能够帮你解决Java byte stream 字节流字节流所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复