字节流(InputStream、OutputStream)
-
字节流是以字节码的形式读取或写出文件数据
-
字节流是所有流基础
-
字节流是以字节码为操作单位所以更适用于操作二进制文件(如:图片文件、音频、视频、压缩包等非文本文件)
-
Java中进行字节流操作的两个基础类(InputStream<字节流>、OutputStream<字节输出流>)
-
在实际使用时我们一般使用两个子类实现字节流操作
(1) FileInputStream:基于文件的字节输入流
(2) FileOutputStream:基于文件的字节输出流
(3) BufferedInputStream:带有缓冲区的字节输入流
(4) BufferedOutputStream:带有缓冲区的字节输出流
1)文件读取(压缩包不可读取,它是二进制的,无法转为char类型,会输出乱码)
若在创建字节输入流对象FileInputStream后面创建inputStreamReader对象并指定所使用编码,inputStreamReader对象就会按照指定的编码方式将读取到的字节转换对应的字符(如果不指定编码,则默认按照UTF-8编码将读取到的字节转换字符)
java
InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"GBK");
java
import java.io.FileInputStream;
import java.io.IOException;
public class InputStreamDemo {
public static void main(String[] args) throws IOException {
//创建字节输入流对象
FileInputStream inputStream = new FileInputStream("D:\\IO流常用方法.txt");
//定义缓冲区
byte[] buf = new byte[1024];
//读取的实际长度
int len = -1;
while ((len = inputStream.read(buf)) != -1) {
//将字节码转换为字符串
String str = new String(buf, 0, len); //buf:读取的字节码 0:起始位置 len:终止位置
System.out.println(str);
}
//关闭输入流对象,释放所占用的资源
inputStream.close();
}
}
2)文件写入
同样,在创建字节输出流对象FileOutputStream后创建outputStreamWriter对象并指定所使用编码,outputStreamWriter对象就会按照指定的编码方式将写入到的字节转换对应的字符
java
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream,"GBK");
java
import java.io.FileOutputStream;
import java.io.IOException;
public class OutputStreamDemo {
public static void main(String[] args) throws IOException {
/**
* 创建字节输出流对象
* 如果输出的目标文件存在则向文件中直接写入内容,如果目标文件不存在则新建文件
* 字节输出流默认以替换的方式写出数据
* 如果需要使用追加的方式向文件中写入内容,则需要再构造方法中加入true参数
*/
FileOutputStream outputStream = new FileOutputStream("D:/redme.txt", true);
String str = "\r\n你好,吃了吗?";// \r\n表示换行
//String str = "不饿"; //可继续输入其他内容
outputStream.write(str.getBytes());
outputStream.close();
}
}
3)文件复制方法
1.不使用带有缓冲区的字节输入流输出流
java
import java.io.*;
public class FileCopy {
public static void main(String[] args) throws IOException {
File srcFile = new File("D:\\钉钉\\3.字节流.rar");
File descFile = new File("D:\\QQ\\3.字节流.rar");
fileCopy(srcFile,descFile);
}
public static void fileCopy(File srcFile,File descFile) throws IOException {
//创建字节输入和输出流
InputStream inputStream = new FileInputStream(srcFile);
OutputStream outputStream = new FileOutputStream(descFile);
//创建一个字节数组做为读取数据的缓冲区
byte[] buf = new byte[1024 * 10];//文件较大时可以 *10
int len = -1;
//获得当前时间的毫秒数
long start = System.currentTimeMillis();
//循环读取数据
while ((len = inputStream.read(buf,0,buf.length)) != -1){
//循环写入到文件中
outputStream.write(buf,0,len);
//刷新输出流,清空输出流管道中的数据
outputStream.flush();
}
//获得当前时间的毫秒数
long end = System.currentTimeMillis();
System.out.println("复制完毕,耗时:"+(end-start)+"毫秒");
//关闭输入和输出流
inputStream.close();
outputStream.close();
}
}
2.使用带有缓冲区的字节输入流输出流 (效率提高)
java
import java.io.*;
public class FileCopyForBuffer {
public static void main(String[] args) throws IOException {
File srcFile = new File("C:\\字节流.rar");
File descFile = new File("D:\\字节流.rar");
fileCopy(srcFile,descFile);
}
/*
文件复制方法
参数1:复制的源文件
参数2:复制的目录文件
*/
public static void fileCopy(File srcFile,File descFile) throws IOException {
//创建字节输入和输出流
InputStream inputStream = new FileInputStream(srcFile);
/**
* 带有缓冲区的字节流
* 该类为一个包装类
* BufferedInputStream:带有缓冲区的字节输入流
* BufferedOutputStream:带有缓冲区的字节输出流
*/
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);//包装类
OutputStream outputStream = new FileOutputStream(descFile);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);//包装类
//创建一个字节数组做为读取数据的缓冲区
byte[] buf = new byte[1024];
int len = -1;
//获得当前时间的毫秒数
long start = System.currentTimeMillis();
//循环读取数据
while ((len = bufferedInputStream.read(buf,0,buf.length)) != -1){
//循环写入到文件中
bufferedOutputStream.write(buf, 0, len);
//刷新输出流,清空输出流管道中的数据
bufferedOutputStream.flush();
}
//获得当前时间的毫秒数
long end = System.currentTimeMillis();
System.out.println("复制完毕,耗时:"+(end-start)+"毫秒");
//关闭输入和输出流
bufferedInputStream.close();
bufferedOutputStream.close();
}
}
4)从输入流中每次读取一行数据
java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
//创建带有缓冲区的字符输入流
BufferedReader reader = new BufferedReader(new FileReader("D:\\IO流常用方法.txt"));
String str = null;
//从输入流中读取一行数据
while ((str = reader.readLine()) != null){
System.out.println(str);
}
}
}
5)BufferedWriter
java
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
/**
* BufferedWriter:带有缓冲区的字符输出流
* 支持换行和字符串写入,无需手动拼接换行符。
*/
public class BufferedWriterDemo {
public static void main(String[] args) throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter("D:/redme.txt"));
writer.write("暗恋小美");
writer.close();
}
}
6)更加便捷的输入输出流操作
1.输入流
java
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;
/**
* 字符流不能设置编码,它只能使用默认编码(UTF-8)
* 字符流时一般使用为UTF-8编码
*/
public class FileReaderDemo {
public static void main(String[] args) throws IOException {
//创建字符输入流
FileReader reader = new FileReader("D:\\IO流常用方法.txt", Charset.forName("GBK"));
char[] buf = new char[1024];
int len=-1;
while ((len = reader.read(buf)) !=-1){
String str = String.valueOf(buf, 0, len);
System.out.println(str);
}
reader.close();
}
}
2.输出流
java
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;
public class FileWriterDemo {
public static void main(String[] args) throws IOException {
FileWriter writer = new FileWriter("D:/redme.txt", Charset.forName("GBK"));
writer.write("小美你好");
writer.close();
}
}