1.IO流概述及其分类
(1)概述:IO流用来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中 java.io
(2)IO流分类:
按照数据流向:输入流和输出流。
按照数据类型:字节流,可以读写任何类型的文件 比如音频 视频 文本文件
字符流,只能读写文本文件
2.字节流
2.1FileOutputStream的三个write()方法
方法 | 功能 |
public void write(int b) | 写一个字节 超过一个字节 砍掉前面的字节 |
public void write(byte[] b) | 写一个字节数组 |
public void write(byte[] b,int off,int len) | 写一个字节数组的一部分 |
public class MyTest2 {
public static void main(String[] args) throws IOException {
FileOutputStream out = new FileOutputStream("a.txt");
//往文件中写入数据
//一次写入一个字节数据
out.write(97);
out.write(98);
out.write(99);
//如果超过一个字节,会丢弃掉多余字节
out.write(300);
// [-26, -120, -111] 我的字节数组
out.write(-26);
out.write(-120);
out.write(-111);
out.write("我爱你".getBytes());
byte[] arr = {97, 98, 99, 100, 101};
out.write(arr);
//一次写入字节数组的一部分
//2 索引 3 字节个数
out.write(arr, 2, 3);
//流使用完毕,记得关闭流
out.close(); //销毁输出流对象,释放系统底层资源
}
}
2.2FileOutputStream写出数据实现换行和追加写入
public class MyTest4 {
public static void main(String[] args) throws IOException {
//参数:true 表示追加写入,false或省略该参数,就不会追加,而是覆盖。
FileOutputStream out = new FileOutputStream("诗.txt", true);
out.write("去年今日此门中,".getBytes());
//写入换行符
out.write("\r\n".getBytes());
out.write("人面桃花相映红。".getBytes());
out.write("\r\n".getBytes());
out.write("人面不知何处去,".getBytes());
out.write("\r\n".getBytes());
out.write("桃花依旧笑春风。".getBytes());
out.write("\r\n".getBytes());
out.close();
}
}
2.3FileInputStream读取数据
方法 | 功能 |
int read() | 一次读取一个字节,如果没有数据返回的就是-1 |
int read(byte[] b) | 一次读取一个字节数组,返回的int类型的值表示的意思是读取到的字节的个数,如果没有数据了就返回-1 |
public class MyTest2 {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("a.txt");
//读取文件数据,
int by = in.read(); //一次读取一个字节数据,返回的是你读取到的那个字节
System.out.println(by);
//System.out.println((char) by);
by = in.read(); //一次读取一个字节数据
System.out.println(by);
by = in.read(); //一次读取一个字节数据
System.out.println(by);
//文件中数据读取完毕,然后读取不到了,返回 -1 我们可以使用 -1 来判断文件是否读取完毕。
by = in.read(); //一次读取一个字节数据
System.out.println(by);
}
}
public class MyTest3 {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("a.txt");
//我们创建一个字节数组,作为缓冲区,
byte[] bytes = new byte[100];
//返回的是你实际读取到的字节个数,
int len = in.read(bytes); //把文件中的字节一次读取满,你这个字节数组
System.out.println(len);
System.out.println("================================");
String s = new String(bytes, 0, len);
System.out.println(s);
in.close(); //不要忘了
}
}
2.4BufferedOutputStream写出数据和读取数据
缓冲思想:
字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,
这是加入了数组这样的缓冲区效果,java本身在设计的时候,
也考虑到了这样的设计思想,所以提供了字节缓冲区流。
BufferedOutputStream的构造方法 | BufferedOutputStream(OutputStream out) |
BufferedInputStream的构造方法 | BufferedInputStream(InputStream in) |
2.5字节流复制文件
(1)基本字节流一次读写一个字节
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class MyTest1 {
public static void main(String[] args) throws IOException {
//复制文件,读取一个字节,写入一个字节来复制
FileInputStream in = new FileInputStream("d:\\video01.avi");
FileOutputStream out = new FileOutputStream("d:\\video02.avi");
int by = 0;
while ((by = in.read()) != -1) {
out.write(by);
}
in.close();
out.close();
}
}
(2)基本字节流一次读写一个字节数组
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class MyTest2 {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("d:\\video01.avi");
FileOutputStream out = new FileOutputStream("d:\\video02.avi");
//定义字节数组,充当缓冲区
byte[] bytes = new byte[1024 * 8];
//定义一个变量,用来记录实际读取到的字节个数
int len = 0;
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush(); //刷新缓冲区
}
in.close();
out.close();
}
}
(3)高效字节流一次读写一个字节数组
public class MyTest3 {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("d:\\video01.avi");
FileOutputStream out = new FileOutputStream("d:\\video02.avi");
BufferedInputStream bin = new BufferedInputStream(in);
BufferedOutputStream bout = new BufferedOutputStream(out);
byte[] bytes = new byte[1024 * 8];
int by = 0;
while ((by = bin.read(bytes)) != -1) {
bout.write(bytes, 0, by);
}
bin.close();
bout.close();
}
}
3.字符流
3.1转换流OutputStreamWriter的使用
(1)构造方法
方法 | 功能 |
OutputStreamWriter(OutputStream out) | 根据默认编码把字节流的数据转换为字符流 |
OutputStreamWriter(OutputStream out,String charsetName) | 根据指定编码把字节流数据转换为字符流 |
(2)字符流写数据的方式
方法 | 功能 |
public void write(int c) | 写一个字符 |
public void write(char[] cbuf) | 写一个字符数组 |
public void write(char[] cbuf,int off,int len) | 写一个字符数组的 一部分 |
public void write(String str) | 写一个字符串 |
public void write(String str,int off,int len) | 写一个字符串的一部分 |
public class MyTest {
public static void main(String[] args) throws IOException {
// OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。
// 它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
// OutputStreamWriter(OutputStream out) 创建使用默认字符编码的 OutputStreamWriter。
//输出流,所关联的文件,如果不存在,会自动创建
//字符流,只能操作文本文件
// OutputStreamWriter(OutputStream out, String charsetName)
// 创建使用指定字符集的 OutputStreamWriter。
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("sroce.txt"), "UTF-8");
out.write('a');
//字符流记得刷新一下
out.flush();
//一次写入一个自付费串
out.write("是字符流通向字节流的桥梁");
out.write("\r\n");
//一次写入字符串的一部分
out.write("否则将接受平台默认的字符集", 7, 6);
out.write("\r\n");
char[] chars = {'a', 'b', 'c', '我', '爱', '你'};
out.write(chars);
out.write("\r\n");
out.write(chars, 3, 3);
out.close(); //关闭并刷新。
}
}
3.2转换流InputStreamReader的使用
(1)构造方法
方法 | 功能 |
InputStreamReader(InputStream is) | 用默认的编码读取数据 |
InputStreamReader(InputStream is,String charsetName) | 用指定的编码读取数据 |
(2)字符流读数据的方式
方法 | 功能 |
public int read() | 一次读取一个字符,如果没有读到 返回-1 |
public int read(char[] cbuf) | 一次读取一个字符数组 如果没有读到 返回-1 |
3.3字符流复制文本文件
(1)一次一个字符
public class MyTest {
public static void main(String[] args) throws IOException {
//一次读写一个字符,来复制文本文件
InputStreamReader reader = new InputStreamReader(new FileInputStream("D:\\MyTest.java"));
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("D:\\test\\MyTest.java"));
while (true) {
int ch = reader.read();
if (ch == -1) {
break;
}
writer.write(ch);
writer.flush();
}
reader.close();
writer.close();
}
}
(2)一次一个字符数组
public class MyTest2 {
public static void main(String[] args) throws IOException {
InputStreamReader reader = new InputStreamReader(new FileInputStream("D:\\MyTest.java"));
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("D:\\test\\MyTest.java"));
//定义一个字符数组来充当缓冲区
char[] chars = new char[1000];
int len = 0; //记录读取到的实际的字符个数
while ((len = reader.read(chars)) != -1) {
System.out.println(len);
writer.write(chars, 0, len);
writer.flush();
}
reader.close();
writer.close();
}
}
3.4FileWriter和FileReader复制文本文件
(1)FileReader和FileWriter的出现
转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,
所以,为了简化我们的书写,转换流提供了对应的子类。
转换流 便捷类
- OutputStreamWriter ------- FileWriter
- InputStreamReader ------- FileReader
public class MyTest {
public static void main(String[] args) throws IOException {
/* 构造方法摘要
FileWriter(File file)
根据给定的 File 对象构造一个 FileWriter 对象。
FileWriter(File file, boolean append)
根据给定的 File 对象构造一个 FileWriter 对象。
FileWriter(String fileName)
根据给定的文件名构造一个 FileWriter 对象。
FileWriter(String fileName, boolean append)
根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。*/
FileReader reader = new FileReader("C:\\Users\\ShenMouMou\\Desktop\\MyTest.java");
FileWriter writer = new FileWriter("C:\\Users\\ShenMouMou\\Desktop\\MyTest3.java");
//定义一个字符数组来充当缓冲区
char[] chars = new char[1000];
int len = 0; //记录读取到的实际的字符个数
while ((len = reader.read(chars)) != -1) {
System.out.println(len);
writer.write(chars, 0, len);
writer.flush();
}
reader.close();
writer.close();
}
}
3.5字符缓冲流的基本使用
高效的字符输出流: BufferedWriter
构造方法: public BufferedWriter(Writer w)
高效的字符输入流: BufferedReader
构造方法: public BufferedReader(Reader e)
(1)字符缓冲区复制文件
public class MyTest5 {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("a.txt"));
BufferedWriter writer = new BufferedWriter(new FileWriter("c.txt"));
//定义一个字符数组来充当缓冲区
char[] chars = new char[1000];
int len = 0; //记录读取到的实际的字符个数
while ((len = reader.read(chars)) != -1) {
System.out.println(len);
writer.write(chars, 0, len);
writer.flush();
}
reader.close();
writer.close();
}
}
(2)字符缓冲流的特殊功能
方法 | 功能 |
BufferedWriter: public void newLine() | 根据系统来决定换行符 具有系统兼容性的换行符 |
BufferedReader: public String readLine() | 一次读取一行数据 ,是以换行符为标记的,读到换行符就换行 没读到数据返回null,包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null |
字符缓冲区一次读一行复制文本文件
public class MyTest6 {
public static void main(String[] args) {
BufferedReader reader = null;
BufferedWriter writer = null;
try {
reader = new BufferedReader(new FileReader("a.txt"));
writer = new BufferedWriter(new FileWriter("e.txt"));
String line = null;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine();
writer.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}