Keyword:
- IO流
- 字节流子类
- FileOutputStream
- FileInputStream
- BufferedOutputStream
- BufferedInputStream
- FileOutputStream和FileInputStream复制文件
- 字符流子类
- 字符流出现的原因及编码表概述和常见编码表
- String类中的编码和解码问题
- OutputStreamWriter
- InputStreamReader
- FileWriter和FileReader复制文本文件
- 字符串高效流
- 综合
IO流
1.IO流的概念
IO流用来处理设备之间的数据传输
2.IO流分类
- 按照数据流向 (站在内存角度)
- 输入流----读入数据
- 输出流----写出数据
- 按照数据类型
- 字节流 可以读写任何类型的文件 比如音频 视频 文本文件
- 字符流 只能读写文本文件
3.IO流的分类
字节流
FileOutputStream类
1.FileOutputStream写出数据
构造方法:
FileOutputStream(File file)
FileOutputStream(String name)
案例演示:
public class Demo {
public static void main(String[] args) {
FileOutputStream out=null;
try {
out = new FileOutputStream(".txt");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
-
创建字节输出流对象了做了几件事情?
- 调用系统资源创建a.txt文件
- 创建了一个out对象
- 把out对象指向这个文件
-
为什么一定要close()?
-
通知系统释放关于管理a.txt文件的资源
-
让Io流对象变成垃圾,等待垃圾回收器对其回收
-
2.FileOutputStream的三个write()方法
public void write(int b):写一个字节 超过一个字节 砍掉前面的字节
public void write(byte[] b):写一个字节数组
public void write(byte[] b,int off,int len):写一个字节数组的一部分
案例演示:
public class Demo {
public static void main(String[] args) {
FileOutputStream out=null;
try {
out = new FileOutputStream(".txt");
out.write(97);
out.write(new byte[]{'1','9','2','9','2','9','2'});
out.write(new byte[]{'1','9','2','9','2','9','2'},1,3);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.FileOutputStream写出数据实现换行和追加写入
案例演示:
public class Demo {
public static void main(String[] args) {
FileOutputStream out = null;
try {
out = new FileOutputStream(".txt", true);
//根据构造函数的重载,true表示追加
out.write(97);
out.write("\r\n".getBytes());
out.write(new byte[]{'1', '9', '2', '9', '2', '9', '2'});
out.write("\r\n".getBytes());
out.write(new byte[]{'1', '9', '2', '9', '2', '9', '2'}, 1, 3);
out.write("\r\n".getBytes());
//windows下的换行符 \r\n
// Linux \n
// Mac \r
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
4.FileOutputStream写出数据加入异常处理
案例演示:
public class Demo {
public static void main(String[] args) {
FileOutputStream out = null;
try {
out = new FileOutputStream(".txt");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileInputStream
1.FileInputStream读取数据一次一个字节
案例演示:
public class Demo {
public static void main(String[] args) {
FileInputStream in = null;
try {
in = new FileInputStream(".txt");
while (in.read()!=-1){
//一个一个的读取字节,当找不到输出-1
System.out.println(in.read());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.字节流复制文本文件
字节流一次读写一个字节复制文本文件
分析:
- a: 创建字节输入流对象和字节输出流对象
- b: 频繁的读写操作
- c: 释放资源
案例演示:
public class Demo {
public static void main(String[] args) {
FileInputStream in = null;
FileOutputStream out=null;
try {
in = new FileInputStream(".txt");
out=new FileOutputStream("a.txt");
int len=0;
while ((len=in.read())!=-1){
out.write(len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.FileInputStream读取数据一次一个字节数组
案例演示: int read(byte[] b):一次读取一个字节数组
public class Demo {
public static void main(String[] args) {
FileInputStream in = null;
try {
in = new FileInputStream(".txt");
int len = 0;
//表示在字节数组中的个数
byte[] bytes = new byte[1024 * 8];
while ((len = in.read()) != -1) {
System.out.println(in.read(bytes, 0, len));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
4.字节流复制文本文件
案例演示:
public class Demo {
public static void main(String[] args) {
FileInputStream in = null;
FileOutputStream out=null;
try {
in = new FileInputStream(".txt");
out=new FileOutputStream("a.txt");
int len=0;
byte[] bytes = new byte[1024 * 8];
while ((len=in.read())!=-1){
out.write(bytes,0,len);
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
out.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
5.FileOutputStream和FileInputStream复制文件(内嵌套文件夹)
案例演示:
public class Demo1 {
public static void main(String[] args) throws IOException {
File file = new File("C:\\Users\\Administrator\\Desktop\\note");
File outfile = new File("C:\\Users\\Administrator\\Downloads\\note");
Copyfile(file, outfile);
}
private static void Copyfile(File file, File outfile) {
outfile.mkdirs();
File[] listFiles = file.listFiles();
for (File listFile : listFiles) {
if (listFile.isFile()) {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream(listFile.getAbsolutePath());
out = new FileOutputStream(outfile.getAbsolutePath() + "\\" + listFile.getName());
int len = 0;
byte[] bytes = new byte[1024 * 8];
while ((len = in.read(bytes)) != -1) {
out.write(bytes);
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} else if (listFile.isDirectory()) {
File file1 = new File(outfile.getAbsolutePath() + "\\" + listFile.getName());
Copyfile(listFile, file1);
}
}
}
}
BufferedOutputStream和BufferedInputStream
字节流四种方式复制MP3并测试效率
案例演示:
通过以下四个代码测试效率。
基本字节流一次读写一个字节 //143
基本字节流一次读写一个字节数组 //8
高效字节流一次读写一个字节 //8
高效字节流一次读写一个字节数组 //8
结论:由于引入了缓冲区的思想,所以读写的速度变快
字符流
字符流出现的原因及编码表概述和常见编码表
String类中的编码和解码问题
转换流OutputStreamWriter
1.构造方法
OutputStreamWriter(OutputStream out):根据默认编码(GBK)把字节流的数据转换为字符流
OutputStreamWriter(OutputStream out,String charsetName):根据指定编码把字节流数据转换为字符流
案例演示:
public class Demo1 {
public static void main(String[] args) throws IOException {
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("a.txt"));
writer.write(97);
writer.flush();
//字符流每次写完,都需要刷新一下
}
}
a.txt文档中显示的是a
2.字符流的5种写数据的方式
方法概述
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 Demo1 {
public static void main(String[] args) throws IOException {
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("a.txt"),"utf-8");
writer.write(97);
writer.write("\r\n");
writer.flush();
writer.write(new char[]{'你','好','世','界'});
writer.write("\r\n");
writer.flush();
writer.write(new char[]{'你','好','世','界'},2,2);
writer.write("\r\n");
writer.flush();
writer.write("你好世界");
writer.write("\r\n");
writer.flush();
writer.write("你好java世界",2,4);
writer.write("\r\n");
//换行符
writer.flush();
//字符流每次写完,都需要刷新一下
writer.close();
//每次结束,都要关闭流,清理内存
}
}
转换流InputStreamReader
1.构造方法
InputStreamReader(InputStream is):用默认的编码(GBK)读取数据
InputStreamReader(InputStream is,String charsetName):用指定的编码读取数据
案例演示:
public class Demo2 {
public static void main(String[] args) throws IOException {
InputStreamReader reader = new InputStreamReader(new FileInputStream("a.txt"));
System.out.println(reader.read());
System.out.println(reader.read());
System.out.println(reader.read());
System.out.println(reader.read());
System.out.println(reader.read());
reader.close();
}
}
----------------------
97
13
10
20320
22909
2.字符流的2种读数据的方式
-
public int read() 一次读取一个字符
案例演示:
public class Demo2 { public static void main(String[] args) throws IOException { InputStreamReader reader = new InputStreamReader(new FileInputStream("a.txt")); while (reader.read()!=-1){ System.out.println(reader.read()); } reader.close(); } }
-
public int read(char[] cbuf) 一次读取一个字符数组 如果没有读到 返回-1
案例演示:
public class Demo2 { public static void main(String[] args) throws IOException { InputStreamReader reader = new InputStreamReader(new FileInputStream("a.txt")); int len = 0; char[] chars = new char[1024 * 8]; while ((len = reader.read(chars)) != -1) { reader.read(chars, 0, len); } reader.close(); } }
3.字符流复制文本文件
案例演示:
public class Demo {
public static void main(String[] args) throws IOException {
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("b.txt"));
InputStreamReader reader = new InputStreamReader(new FileInputStream("a.txt"));
int len=0;
char[] chars = new char[100];
while ((len=reader.read(chars))!=-1){
writer.write(chars,0,len);
writer.flush();
}
writer.close();
}
}
FileWriter和FileReader
1.概念:
转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,所以,为了简化书写,转换流提供了对应的子类。
转换流 便捷类
OutputStreamWriter ------- FileWriter
InputStreamReader ------- FileReader
案例演示:FileWriter和FileReader复制文本文件
public class Demo3 {
public static void main(String[] args) throws IOException {
FileWriter writer = new FileWriter("c.txt");
FileReader reader = new FileReader("a.txt");
int len = 0;
char[] chars = new char[100];
while ((len = reader.read(chars)) != -1) {
writer.write(chars, 0, len);
writer.flush();
}
writer.close();
reader.close();
}
}
字符缓冲流
1.字符缓冲流复制文本文件
public class Demo4 {
public static void main(String[] args) throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter("d.txt"));
BufferedReader reader = new BufferedReader(new FileReader("a.txt"));
int len = 0;
char[] chars = new char[1000];
while ((len = reader.read(chars)) != -1) {
writer.write(chars, 0, len);
writer.flush();
}
writer.close();
reader.close();
}
}
2.字符缓冲流的特殊功能
BufferedWriter:public void newLine():根据系统来决定换行符 具有系统兼容性的换行符
BufferedReader:public String readLine():一次读取一行数据 是以换行符为标记的 读到换行符就换行 没读到数据返回null,包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
案例演示:
public class Demo4 {
public static void main(String[] args) throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter("d.txt"));
BufferedReader reader = new BufferedReader(new FileReader("a.txt"));
String line=reader.readLine();
while (line!=null) {
writer.write(line);
writer.newLine();
writer.flush();
}
writer.close();
reader.close();
}
}
3.字符缓冲流的特殊功能复制文本文件
案例演示:
public class Demo4 {
public static void main(String[] args) throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter("d.txt"));
BufferedReader reader = new BufferedReader(new FileReader("a.txt"));
String line=reader.readLine();
while (line!=null) {
writer.write(line);
writer.newLine();
writer.flush();
}
writer.close();
reader.close();
}
}
综合
1.把集合中的数据存储到文本文件
案例演示:
需求:把ArrayList集合中的字符串数据存储到文本文件
public class Demo2 {
//创建一个ArrayList集合
//添加元素
//创建一个高效的字符输出流对象
//遍历集合,获取每一个元素,把这个元素通过高效的输出流写到文本文件中
//释放资源
public static void main(String[] args) throws IOException {
ArrayList<String> list = new ArrayList<>();
list.add("zhangsan");
list.add("lisi");
list.add("wangeu");
BufferedWriter writer = new BufferedWriter(new FileWriter("a.txt"));
for (String s : list) {
writer.write(s);
writer.newLine();
writer.flush();
}
writer.close();
}
}
2.把文本文件中的数据存储到集合中
案例演示:
需求:从文本文件中读取数据(每一行为一个字符串数据)到集合中,并遍历集合
public class Demo1 {
public static void main(String[] args) throws IOException {
ArrayList<String> list = new ArrayList<>();//创建一个集合
BufferedReader reader = new BufferedReader(new FileReader("a.txt"));//创建一个高效的字符传输流
String line=null;//用来记录所查找的字符串
while ((line=reader.readLine())!=null){
//如果判断下一行存在字符串,则将读到的字符串添加到集合中
list.add(line);
}
reader.close();
for (String s : list) {
System.out.println(s);
}
//集合的遍历
}
}
3.随机获取文本文件中的姓名
案例演示:
需求:我有一个文本文件,每一行是一个学生的名字,请写一个程序,每次允许随机获取一个学生名称
创建一个高效的字符输入流对象
创建集合对象
读取数据,把数据存储到集合中
产生一个随机数,这个随机数的范围是 0 - 集合的长度 . 作为: 集合的随机索引
根据索引获取指定的元素
输出
释放资源
public class Demo2 {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("a.txt"));
Random random = new Random();
ArrayList<String> list = new ArrayList<>();
String len=null;
while ((len=reader.readLine())!=null){
list.add(len);
}
reader.close();
int num = random.nextInt(list.size());
System.out.println(list.get(num));
}
}
4.复制多级文件夹
案例演示:
public class Demo3 {
public static void main(String[] args) throws IOException {
File sourcefile = new File("C:\\Users\\Administrator\\Desktop\\测试图片");
File aimfile = new File("E:\\测试图片");
CopyFile(sourcefile, aimfile);
}
private static void CopyFile(File sourcefile, File aimfile) throws IOException {
if (!aimfile.exists()) {
aimfile.mkdirs();
File[] listFiles = sourcefile.listFiles();
for (File listFile : listFiles) {
if (listFile.isFile()) {
FileInputStream in = new FileInputStream(listFile);
File file = new File(aimfile, listFile.getName());
FileOutputStream out = new FileOutputStream(file);
int len=0;
byte[] bytes = new byte[1024 * 8];
while ((len=in.read(bytes))!=-1){
out.write(bytes,0,len);
out.flush();
}
in.close();
out.close();
}else {
File file = new File(aimfile, listFile.getName());
CopyFile(listFile,file);
}
}
}
}
}
5.复制指定目录下指定后缀名的文件并修改名称
案例演示:
public class Demo3 {
public static void main(String[] args) throws IOException {
File sourcefile = new File("C:\\Users\\Administrator\\Desktop\\测试图片");
File aimfile = new File("E:\\测试图片");
CopyFile(sourcefile, aimfile);
}
private static void CopyFile(File sourcefile, File aimfile) throws IOException {
if (!aimfile.exists()) {
aimfile.mkdirs();
File[] listFiles = sourcefile.listFiles();
for (File listFile : listFiles) {
if (listFile.isFile()) {
FileInputStream in = new FileInputStream(listFile);
String name = listFile.getName();
if (name.endsWith(".jpg")) {
name = name.replace(".jpg", ".png");
}
//更改后缀名
File file = new File(aimfile, name);
FileOutputStream out = new FileOutputStream(file);
int len = 0;
byte[] bytes = new byte[1024 * 8];
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush();
}
in.close();
out.close();
} else {
File file = new File(aimfile, listFile.getName());
CopyFile(listFile, file);
}
}
}
}
}
6.键盘录入学生信息按照总分排序并写入文本文件
案例演示:
需求:键盘录入3个学生信息(姓名,语文成绩(chineseScore),数学成绩(mathScore),英语成绩(englishScore)),按照总分从高到低存入文本文件
创建一个学生类: 姓名,语文成绩,数学成绩,英语成绩
因为要排序,所以需要选择TreeSet进行存储学生对象
键盘录入学生信息,把学生信息封装成一个学生对象,在把学生对象添加到集合中
创建一个高效的字符输出流对象
遍历集合,把学生的信息写入到指定的文本文件中
释放资源
public Student() {
}
public int totallyScore() {
return yuScore+sxScore+yyScore;
}
public Student(String name, int yuScore, int sxScore, int yyScore) {
this.name = name;
this.yuScore = yuScore;
this.sxScore = sxScore;
this.yyScore = yyScore;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getYuScore() {
return yuScore;
}
public void setYuScore(int yuScore) {
this.yuScore = yuScore;
}
public int getSxScore() {
return sxScore;
}
public void setSxScore(int sxScore) {
this.sxScore = sxScore;
}
public int getYyScore() {
return yyScore;
}
public void setYyScore(int yyScore) {
this.yyScore = yyScore;
}
}
public class Demo4 {
public static void main(String[] args) throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter("d.txt",true));
TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int num=s1.totallyScore()-s2.totallyScore();
int num2=num==0?s1.getName().compareTo(s2.getName()):num;
return -num2;
}
});
System.out.println("-----------欢迎使用本系统---------");
for (int i = 1; i <= 3; i++) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入第" + i + "个的姓名");
String name = sc.nextLine();
System.out.println("请输入第" + i + "个人的语文成绩");
int yuwen = sc.nextInt();
System.out.println("请输入第" + i + "个人的数学成绩");
int shuxue = sc.nextInt();
System.out.println("请输入第" + i + "个人的英语成绩");
int yingyu = sc.nextInt();
Student student = new Student(name, yuwen, shuxue, yingyu);
treeSet.add(student);
}
writer.write("-------------成绩单---------------");
writer.newLine();
writer.flush();
writer.write("编号"+"\t"+"姓名"+"\t"+"语文"+"\t"+"数学"+"\t"+"英语"+"\t"+"总分");
writer.newLine();
writer.flush();
int index=1;
for (Student student : treeSet) {
writer.write(index+"\t"+student.getName()+"\t"+student.getYuScore()+"\t"+student.getSxScore()+"\t"+student.getYyScore()+"\t"+student.totallyScore());
writer.newLine();
writer.flush();
index++;
}
writer.close();
}
}