字符流和字节流
字符流:
FileReader
FileWriter。
char[]
BufferedReader
BufferedWriter
字节流:
InputStream OutputStream
byte[]
通过字节流的缓冲区完成复制
/*
需求,想要操作图片数据。这时就要用到字节流。
复制一个图片.
*/
// 通过字节流的缓冲区完成复制。
public static void copy_1() throws IOException {
BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\0.mp3"));
BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\1.mp3"));
int by = 0;
while ((by = bufis.read()) != -1) {
bufos.write(by);
}
bufos.close();
bufis.close();
}
/*
1,
源:键盘录入。
目的:控制台。
2,需求:想把键盘录入的数据存储到一个文件中。
源:键盘。
目的:文件。
3,需求:想要将一个文件的数据打印在控制台上。
源:文件。
目的:控制台。
流操作的基本规律:
最痛苦的就是流对象有很多,不知道该用哪一个。
通过三个明确来完成。
1,明确源和目的。
源:输入流。InputStream Reader
目的:输出流。OutputStream Writer。
2,操作的数据是否是纯文本。
是:字符流。
不是:字节流。
3,当体系明确后,在明确要使用哪个具体的对象。
通过设备来进行区分:
源设备:内存,硬盘。键盘
目的设备:内存,硬盘,控制台。
1,将一个文本文件中数据存储到另一个文件中。复制文件。
源:因为是源,所以使用读取流。InputStream Reader
是不是操作文本文件。
是!这时就可以选择Reader
这样体系就明确了。
接下来明确要使用该体系中的哪个对象。
明确设备:硬盘。上一个文件。
Reader体系中可以操作文件的对象是 FileReader
是否需要提高效率:是!。加入Reader体系中缓冲区 BufferedReader.
FileReader fr = new FileReader("a.txt");
BufferedReader bufr = new BufferedReader(fr);
目的:OutputStream Writer
是否是纯文本。
是!Writer。
设备:硬盘,一个文件。
Writer体系中可以操作文件的对象FileWriter。
是否需要提高效率:是!。加入Writer体系中缓冲区 BufferedWriter
FileWriter fw = new FileWriter("b.txt");
BufferedWriter bufw = new BufferedWriter(fw);
练习:将一个图片文件中数据存储到另一个文件中。复制文件。要按照以上格式自己完成三个明确。
---------------------------------------
2,需求:将键盘录入的数据保存到一个文件中。
这个需求中有源和目的都存在。
那么分别分析
源:InputStream Reader
是不是纯文本?是!Reader
设备:键盘。对应的对象是System.in.
不是选择Reader吗?System.in对应的不是字节流吗?
为了操作键盘的文本数据方便。转成字符流按照字符串操作是最方便的。
所以既然明确了Reader,那么就将System.in转换成Reader。
用了Reader体系中转换流,InputStreamReader
InputStreamReader isr = new InputStreamReader(System.in);
需要提高效率吗?需要!BufferedReader
BufferedReader bufr = new BufferedReader(isr);
目的:OutputStream Writer
是否是存文本?是!Writer。
设备:硬盘。一个文件。使用 FileWriter。
FileWriter fw = new FileWriter("c.txt");
需要提高效率吗?需要。
BufferedWriter bufw = new BufferedWriter(fw);
**************
扩展一下,想要把录入的数据按照指定的编码表(utf-8),将数据存到文件中。
目的:OutputStream Writer
是否是存文本?是!Writer。
设备:硬盘。一个文件。使用 FileWriter。
但是FileWriter是使用的默认编码表。GBK.
但是存储时,需要加入指定编码表utf-8。而指定的编码表只有转换流可以指定。
所以要使用的对象是OutputStreamWriter。
而该转换流对象要接收一个字节输出流。而且还可以操作的文件的字节输出流。FileOutputStream
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");
需要高效吗?需要。
BufferedWriter bufw = new BufferedWriter(osw);
所以,记住。转换流什么使用。字符和字节之间的桥梁,通常,涉及到字符编码转换时,
需要用到转换流。
*/ }
class TransStreamDemo2 {
public static void main(String[] args) throws IOException {
System.setIn(new FileInputStream("PersonDemo.java"));
System.setOut(new PrintStream("zzz.txt"));
// 键盘的最常见写法。
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
String line = null;
while ((line = bufr.readLine()) != null) {
if ("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
}
}
字符流写入缓冲区
/*
* 缓冲区的出现是为了提高流的操作效率而出现的。
*
* 所以在创建缓冲区之前,必须要先有流对象。
*
* 该缓冲区中提供了一个跨平台的换行符。 newLine();
*
*/
import java.io.*;
class BufferedWriterDemo {
public static void main(String[] args) throws IOException {
// 创建一个字符写入流对象。
FileWriter fw = new FileWriter("buf.txt");
// 为了提高字符写入流效率。加入了缓冲技术。
// 只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。
BufferedWriter bufw = new BufferedWriter(fw);
for (int x = 1; x < 5; x++) {
bufw.write("abcd" + x);
bufw.newLine();
bufw.flush();
}
// 记住,只要用到缓冲区,就要记得刷新。
// bufw.flush();
// 其实关闭缓冲区,就是在关闭缓冲区中的流对象。
bufw.close();
}
}
class CopyTextByBuf {
public static void main(String[] args) {
BufferedReader bufr = null;
BufferedWriter bufw = null;
try {
bufr = new BufferedReader(new FileReader("BufferedWriterDemo.java"));
bufw = new BufferedWriter(new FileWriter("bufWriter_Copy.txt"));
String line = null;
while ((line = bufr.readLine()) != null) {
bufw.write(line);
bufw.newLine();
bufw.flush();
}
} catch (IOException e) {
throw new RuntimeException("读写失败");
} finally {
try {
if (bufr != null)
bufr.close();
} catch (IOException e) {
throw new RuntimeException("读取关闭失败");
}
try {
if (bufw != null)
bufw.close();
} catch (IOException e) {
throw new RuntimeException("写入关闭失败");
}
}
}
}
字符流读入缓冲区
/*
* 字符读取流缓冲区: 该缓冲区提供了一个一次读一行的方法 readLine,方便于对文本数据的获取。 当返回null时,表示读到文件末尾。
*
* readLine方法返回的时候只返回回车符之前的数据内容。并不返回回车符。
*/
class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
// 创建一个读取流对象和文件相关联。
FileReader fr = new FileReader("buf.txt");
// 为了提高效率。加入缓冲技术。将字符读取流对象作为参数传递给缓冲对象的构造函数。
BufferedReader bufr = new BufferedReader(fr);
String line = null;
while ((line = bufr.readLine()) != null) {
System.out.print(line);
}
bufr.close();
}
}
// 读取一个.java文件,并打印在控制台上。
class FileReaderTest {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("DateDemo.java");
char[] buf = new char[1024];
int num = 0;
while ((num = fr.read(buf)) != -1) {
System.out.print(new String(buf, 0, num));
}
fr.close();
}
}
字符流复制文件
//将C盘一个文本文件复制到D盘。
/*
复制的原理:
其实就是将C盘下的文件数据存储到D盘的一个文件中。
步骤:
1,在D盘创建一个文件。用于存储C盘文件中的数据。
2,定义读取流和C盘文件关联。
3,通过不断的读写完成数据存储。
4,关闭资源。
*/
copy_2() 使用缓冲区
public static void copy_2() {
FileWriter fw = null;
FileReader fr = null;
try {
fw = new FileWriter("SystemDemo_copy.txt");
fr = new FileReader("SystemDemo.java");
char[] buf = new char[1024];
int len = 0;
while ((len = fr.read(buf)) != -1) {
fw.write(buf, 0, len);
}
} catch (IOException e) {
throw new RuntimeException("读写失败");
} finally {
if (fr != null)
try {
fr.close();
} catch (IOException e) {
}
if (fw != null)
try {
fw.close();
} catch (IOException e) {
}
}
}
// 从C盘读一个字符,就往D盘写一个字符。
public static void copy_1() throws IOException {
// 创建目的地。
FileWriter fw = new FileWriter("RuntimeDemo_copy.txt");
// 与已有文件关联。
FileReader fr = new FileReader("RuntimeDemo.java");
int ch = 0;
while ((ch = fr.read()) != -1) {
fw.write(ch);
}
fw.close();
fr.close();
}
字节流缓冲
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileByte {
public static void main(String[] args) {
// 复制文件的起始时间
long s = System.currentTimeMillis();
// 定义输入\输出流为mull
FileInputStream fis = null;
FileOutputStream fos = null;
// 手动抛出异常
try {
// 读取文件
fis = new FileInputStream("d:\\digui.mp4");
// 读取完毕复制的文件
fos = new FileOutputStream("d:\\dd.mp4");
// 定义一个字节数组 存到数组b中
byte[] b = new byte[1024 * 10];
// 起始长度为0
int len = 0;
// while(){} 循环 一边读取 ,一边写入(复制)文件
while ((len = fis.read(b)) != -1) {
fos.write(b, 0, len);
fos.flush(); // 文件刷新
}
} catch (Exception e) {
System.out.println(e);
throw new RuntimeException("文件复制失败"); // 手动抛除异常
// 最终执行语句
} finally {
// 复制的文件不为空时 关闭释放资源
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
System.out.println(e);
throw new RuntimeException("文件复制失败");
}
}
}
}
}
// 复制文件的结束时间 单位:ms 毫秒
long e = System.currentTimeMillis();
System.out.println(e-s);
}
}