在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成。程序中的输入输出都是以流的形式保存的,流中保存的实际上全都是字节文件。
字节流与字符流
在java.io包中操作文件内容的主要有两大类:字节流、字符流,两类都分为输入和输出操作。在字节流中输出数据主要是使用OutputStream完成,输入使的是InputStream,在字符流中输出主要是使用Writer类完成,输入流主要使用Reader类完成。(这四个都是抽象类)
方式一:通过字节数组来读取
public static void readAndWriteFileByBytes(String path) {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(path.toString());
out = new FileOutputStream("E://abc//c.jpg");
byte[] buf = new byte[1024*1];
int len = 0;
while ((len =in.read(buf))!=-1) {
out.write(buf, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (out!=null || in!=null){
try {
out.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
out=null; //去除引用,这样处理可以加快清理的速度
in=null;
}
报错:
java.io.FileNotFoundException: E:\abc (拒绝访问。)
out = new FileOutputStream(“E://abc//c.jpg”) 输出的位置,这里有一个我自己认为的坑,当时我懵逼了,就是输出到这个目录下啊,怎么报错了呢,查了很多资料才发现,输出的是一个具体的路径,也就是到哪个文件。(我自己的理解:输出是以流的形式输出的,肯定要有相应的同种类型的文件接受流才对)
out = new FileOutputStream(“E://abc//c.jpg”) 这样就没有问题啦,
方式二: 一个一个字节的读取
public static void readAndWriteFileByByte(String path) throws IOException {
File file = new File(path);
FileInputStream in = new FileInputStream(file);
FileOutputStream out = new FileOutputStream("E:/abc/a.jpg");
int len = 0;
while ((len = in.read()) != -1){
out.write(len);
}
in.close();
out.close();
}
方式一: 一个一个字节的读取
public static void readAndWriteFileByBufferedOutputStream(File file) throws IOException {
BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream("E:\\a.txt"));
//byte[] buffer = new byte[1024];
int read = 0;
while ((read = inputStream.read())!=-1){
System.out.println(read);
//outputStream.write(buffer,0,read);
outputStream.write(read);
//outputStream.flush();//刷新此缓冲的输出流。这将强制将任何缓冲的输出字节写出到基础输出流。
}
inputStream.close();
outputStream.close();
}
方式二:通过字节数组来读取
public static void readAndWriteFileByBufferedOutputStream(File file) throws IOException {
BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream("E:\\a.txt"));
byte[] buffer = new byte[1024];
int read = 0;
while ((read = inputStream.read(buffer))!=-1){
System.out.println(read);
outputStream.write(buffer,0,read);
}
inputStream.close();
outputStream.close();
}
注意:flush() 刷新缓冲的输出流。这将强制将任何缓冲的输出字节写出到基础输出流,也就是说可以不用关闭流,强制性的写到磁盘上,建议在文件关闭前刷新一下
Tips:流的关闭也是有顺序的
一般情况下是:先打开的后关闭,后打开的先关闭
另一种情况:看依赖关系,如果流a依赖流b,应该先关闭流a,再关闭流b
例如处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b
当然完全可以只关闭处理流,不用关闭节点流。处理流关闭的时候,会调用其处理的节点流的关闭方法
如果将节点流关闭以后再关闭处理流,会抛出IO异常
示例:
public static void readAndWriteFileByBufferedOutputStream(File file) {
FileInputStream fileInputStream = null;
BufferedOutputStream outputStream=null;
FileOutputStream fileOutputStream = null;
BufferedInputStream inputStream = null;
try {
inputStream = new BufferedInputStream(fileInputStream);
outputStream = new BufferedOutputStream(new FileOutputStream("E:\\a.txt"));
fileInputStream = new FileInputStream(file);
fileOutputStream = new FileOutputStream("E:\\a.txt");
byte[] buffer = new byte[1024];
int read = 0;
while ((read = inputStream.read(buffer))!=-1){
System.out.println(read);
outputStream.write(buffer,0,read);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fileInputStream!= null){
try {
fileInputStream.close();
if (fileOutputStream!=null){
fileOutputStream.close();
}
outputStream.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
java.io.IOException: Stream closed
at java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:159)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
at java.io.FilterInputStream.read(FilterInputStream.java:107)
at com.etime.homework.test.DateDemo.readAndWriteFileByBufferedOutputStream(DateDemo.java:229)
at com.etime.homework.test.DateDemo.main(DateDemo.java:20)
方式一: 一个一个字符的读取
public static void ReaderAndWriterFileByChar(String path) throws IOException {
FileReader fileReader = new FileReader(path);
File file;
FileWriter fileWriter = new FileWriter("写出的路径", true);
int len = 0;
while ((fileReader.read())!=-1){
fileWriter.write(len);
}
fileWriter.flush();
fileReader.close();
fileWriter.close();
}
方式二: 通过字符数组读取
public static void ReaderAndWriterFileByChars(String path) throws IOException{
FileReader fileReader = new FileReader(path);
File file;
FileWriter fileWriter = new FileWriter("", true);
int len = 0;
char[] chars = new char[1024];
while ((len = fileReader.read(chars))!=-1){
fileWriter.write(chars,0,len);
}
fileWriter.flush();
fileReader.close();
fileWriter.close();
}
方式一: 一个一个字符的读取
public static void bufferReaderAndWriterFileByChar (String path) throws IOException{
BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("写出的路径"));
int len =0;
while ((len = bufferedReader.read())!=-1){
bufferedWriter.write(len);
}
bufferedWriter.flush();
bufferedReader.close();
bufferedWriter.close();
}
方式二: 通过字符数组读取
public static void bufferReaderAndWriterFileByChars (String path) throws IOException{
BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(" 写出的路径"));
int len =0;
char[] chars = new char[1024];
while ((len = bufferedReader.read(chars))!=-1){
bufferedWriter.write(chars,0,len);
}
bufferedWriter.flush();
bufferedReader.close();
bufferedWriter.close();
}
方式三:一行一行的读取
public static void bufferReaderAndWriterFileByLine (String path) throws IOException{
BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("写出的路径"));
String line ="";
while ((line = bufferedReader.readLine())==null){
bufferedWriter.write(line);
bufferedWriter.newLine();//注意换行,不建议使用 \n 或者 \r\n
}
bufferedWriter.flush();
bufferedReader.close();
bufferedWriter.close();
}
一般情况下,我们在使用时, 如果目的对象是文本,建议使用带缓冲的的字符流,效率较高。
在读取图片,音频之类的,使用字节流较好