javaIO流注意事项

1.字符流出现的原因

1.1 字符流出现的原因及编码表概述

  • 字符流出现的原因:由于字节流操作中文不是特别方便,所以,java就提供了字符流。
  • 字符流: 字符流 = 字节流 + 编码表

2.String中的编解码问题

2.1 String类中的编码和解码问题

  • String(byte[] bytes, String charsetName):通过指定的字符集解码字节数组
  • byte[] getBytes(String charsetName):使用指定的字符集合把字符串编码为字节数组
  • 编码:把看得懂的变成看不懂的: String – byte[]
  • 解码:把看不懂的变成看得懂的: byte[] – String

3.转换流[掌握]

3.1 转换流OutputStreamWriter的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* 字符输出流: OutputStreamWriter (转换输出流) 字符流通向字节流的桥梁
* 构造方法:
* public OutputStreamWriter(OutputStream out): 使用默认字符集
* public OutputStreamWriter(OutputStream out , String charsetName): 使用指定的字符集
* 字符输入流: InputStreamReader (转换输入流) 字节流通向字符流的桥梁
* 构造方法:
* public InputStreamReader(InputStream in) 使用的默认的编码表(GBK)
* public InputStreamReader(InputStream in , String charsetName) 使用指定的编码表
*/

public class OutputStreamWriterDemo {
public static void main(String[] args) throws IOException {
// 创建: OutputStreamWriter
// 创建: OutputStream的对象
// FileOutputStream fos = new FileOutputStream("a.txt") ;
// OutputStreamWriter osw = new OutputStreamWriter(fos) ;
// OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt")) ;
// public InputStreamReader(InputStream in , String charsetName) 使用指定的编码表
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt") , "UTF-8") ;
// 调用方法
osw.write("中国") ;
// 释放资源
osw.close() ;
}
}

3.2 转换流InputStreamReader的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class InputStreamReaderDemo {
public static void main(String[] args) throws IOException {
// 创建对象InputStreamReader的对象
// public InputStreamReader(InputStream in): 使用的默认的编码表(GBK)
// FileInputStream fis = new FileInputStream("a.txt") ;
// InputStreamReader isr = new InputStreamReader(fis) ;
// InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt")) ; // 默认的字符集就是GBK

// public InputStreamReader(InputStream in , String charsetName) 使用指定的编码表
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt") , "utf-8") ;
// 读取数据
int ch = 0 ;
while((ch = isr.read()) != -1){
System.out.print((char)ch);
}
// 释放资源
isr.close() ;
}
}

3.3 字符流的5种写数据的方式

1
2
3
4
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)

3.4 字符流的2种读数据的方式

1
2
public int read()
public int read(char[] cbuf)

3.5 高效流FileWriter和FileReader

3.6 字符缓冲流的基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/**
* 高效的字符输入流 BufferedReader
* 高效的字符输出流 BufferedWriter
*/
public class BufferedWriterDemo {

public static void main(String[] args) throws IOException {
//写数据的方式
// write() ;
// 读取数据的方式
read() ;
}

/**
* 使用高效的字符输入流进行读取数据
* @throws IOException
*/
private static void read() throws IOException{
// 创建高效的字符输入流对象
// public BufferedReader(Reader in)
// BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("c.txt"))) ;
BufferedReader br = new BufferedReader(new FileReader("c.txt")) ;
// 读取数据
// int ch = 0 ;
// while((ch = br.read()) != -1){
// System.out.print((char)ch);
// }
char[] chs = new char[1024] ;
int len = 0 ;
while((len = br.read(chs)) != -1){
System.out.print(new String(chs , 0 , len));
}
// 释放资源
br.close() ;
}

/**
* 使用高效的字符输出流进行写数据
* @throws IOException
*/
private static void write() throws IOException {
// 创建BufferedWriter对象
// public BufferedWriter(Writer out)
// OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("c.txt")) ;
// BufferedWriter bw = new BufferedWriter(osw) ;
// BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("c.txt"))) ;
BufferedWriter bw = new BufferedWriter(new FileWriter("c.txt")) ;
// 写数据
bw.write("你好") ;
// 释放资源
bw.close() ;
}
}

3.7 字符缓冲流的特殊功能

1
2
3
BufferedWriter:	public void newLine():根据系统来决定换行符
BufferedReader: public String readLine():一次读取一行数据
包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null

4.IO流的练习题

4.1 字符流复制文本文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
// 创建转换输入流对象
InputStreamReader isr = new InputStreamReader(new FileInputStream("OutputStreamWriterDemo.java")) ;
// 创建转换输出流对象
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("copyFile.java")) ;
// 复制文件
// 一次读取一个字符复制
// int ch = 0 ;
// while((ch = isr.read()) != -1){
// osw.write(ch) ;
// }
// 一次读取一个字符数组复制文件
char[] chs = new char[1024] ;
int len = 0 ;
while((len = isr.read(chs)) != -1){
osw.write(chs, 0, len) ;
}
// 释放资源
osw.close() ;
isr.close() ;
}
}

4.2 FileWriter和FileReader复制文本文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
// 创建高效的字符输入流对象
BufferedReader br = new BufferedReader(new FileReader("OutputStreamWriterDemo.java")) ;
// 创建高效的字符输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("copyFile3.java")) ;
// 一次读取一个字符数组复制文件
char[] chs = new char[1024] ;
int len = 0;
while((len = br.read(chs)) != -1){
bw.write(chs, 0, len) ;
}
// 释放资源
bw.close() ;
br.close() ;
}
}

4.3 字符缓冲流的特殊功能复制文本文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
/**
* 需求: 使用高效的字符流中特有的功能复制文本文件
*/
// 创建高效的字符输入流对象
BufferedReader br = new BufferedReader(new FileReader("OutputStreamWriterDemo.java")) ;

// 高效的字符输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("copyFile4.java")) ;

// 复制文件
// 一次读取一行复制文件
String line = null ;
while((line = br.readLine()) != null) {
bw.write(line) ;
bw.newLine() ;
bw.flush() ;
}
// 释放资源
bw.close() ;
br.close() ;
}
}

4.4 把集合中的数据存储到文本文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public static void main(String[] args) throws IOException {
/**
* 把ArrayList集合中的数据存储到文本文件中
* 分析:
* 1: 创建ArrayList集合对象
* 2: 添加数据
* 3: 创建高效的字符输出流对象
* 4: 遍历集合,获取每一个元素,然后通过流对象写出去
* 5: 释放资源
*/
// 创建ArrayList集合对象
ArrayList<String> al = new ArrayList<String>() ;
// 添加数据
al.add("西施") ;
al.add("貂蝉") ;
al.add("杨玉环") ;
al.add("王昭君") ;
// 创建高效的字符输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("names.txt")) ;
// 遍历集合,获取每一个元素,然后通过流对象写出去
for(String name : al) {
bw.write(name) ;
bw.newLine() ;
bw.flush() ;
}
// 释放资源
bw.close() ;
}

4.5 把文本文件中的数据存储到集合中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public static void main(String[] args) throws IOException {
/**
* 从文本文件中读取数据(每一行为一个字符串数据)到集合中,并遍历集合
* 分析:
* 1: 创建高效的字符输入流对象
* 2: 创建集合对象
* 3: 读取文本文件中的数据,将数据存储到集合中
* 4: 释放资源
* 5: 遍历集合
*/
// 1: 创建高效的字符输入流对象
BufferedReader br = new BufferedReader(new FileReader("names.txt")) ;
// 2: 创建集合对象
ArrayList<String> al = new ArrayList<String>() ;
// 3: 读取文本文件中的数据,将数据存储到集合中
String line = null ; // 作用: 用来记录读取到的行数据
while((line = br.readLine()) != null) {
al.add(line) ;
}
// 4: 释放资源
br.close() ;
// 5: 遍历集合
for(String name : al) {
System.out.println(name);
}
}

4.6 随机获取文本文件中的姓名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void main(String[] args) throws IOException {
// 1: 创建集合对象
ArrayList<String> students = new ArrayList<String> () ;
// 2: 创建BufferedReader对象
BufferedReader br = new BufferedReader(new FileReader("students.txt")) ;
// 3: 读取数据,把数据存储到集合中
String line = null ;
while((line = br.readLine()) != null) {
students.add(line) ;
}
// 4: 释放资源
br.close() ;
// 5: 生成一个随机数
Random random = new Random() ;
int index = random.nextInt(students.size());
// 6: 把生成的随机数作为集合元素的索引,来获取一个元素
String name = students.get(index) ;
// 7: 把获取到的元素打印到控制台
System.out.println(name);
}

4.7 复制单级文件夹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static void main(String[] args) throws IOException {
/**
* 需求: 把C:\\course这个文件夹复制到D:\\course盘下
* 分析:
* 1: 把C:\\course这个目录封装成一个File对象
* 2: 把D:\\course这个目录封装成一个File对象
* 3: 判断D:\\course是否存在,如果存在就创建一个文件夹
* 4: 获取C:\\course这个目录下所有的文件对应的File数组
* 5: 遍历数组,获取元素进行复制
*/
// 把C:\\course这个目录封装成一个File对象
File srcFolder = new File("C:\\course") ;
// 把D:\\course这个目录封装成一个File对象
File destFolder = new File("D:\\course") ;
// 判断D:\\course是否存在,如果存在就创建一个文件夹
if(!destFolder.exists()){
destFolder.mkdir() ;
}
// 复制文件夹
IOUtils.copyFolder(srcFolder, destFolder, null) ;
}

4.8 复制指定目录下指定后缀名的文件并修改名称

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public static void main(String[] args) throws IOException {
/**
* 把C:\\demo这个目录下所有的以.java结尾的文件复制到D:\\demo中,然后将这个文件的后缀名更改为.jad
*/
// 把C:\\demo这个目录下所有的以.java结尾的文件复制到D:\\demo中
// 1: 把C:\\demo这个目录封装成一个File对象
File srcFolder = new File("C:\\demo") ;
// 2: 把D:\\demo这么目录封装成一个File对象
File destFolder = new File("D:\\demo") ;
// 3: 判断D:\\demo这个路径是否存在
if(!destFolder.exists()) {
destFolder.mkdir() ;
}
// 调用方法
IOUtils.copyFolder(srcFolder, destFolder, new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return new File(dir , name).isFile() && name.endsWith(".java") ;
}
}) ;
System.out.println("-----------------------------------------------------");
// 获取destFolder下所有的文件对应的File数组
File[] files = destFolder.listFiles() ;
for(File f : files) {
// 创建目标文件名称
String destFileName = f.getName().replace(".java", ".jad") ;
// 创建目标文件
File destFile = new File(destFolder , destFileName) ;
// 调用
f.renameTo(destFile) ;
}
}

4.7和4.8工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class IOUtils {

public static void copyFolder(String srcPahtName , String destPathName , FilenameFilter filenameFilter) throws IOException {
File srcFolder = new File(srcPahtName) ;
File destFolder = new File(destPathName) ;
if(!destFolder.exists()) {
destFolder.mkdir() ;
}
copyFolder(srcFolder , destFolder , filenameFilter) ;
}

public static void copyFolder(File srcFolder , File destFolder , FilenameFilter filenameFilter) throws IOException {
File[] files = null ;
if(filenameFilter == null) {
files = srcFolder.listFiles() ;
}else {
files = srcFolder.listFiles(filenameFilter) ;
}
// 遍历
for(File f : files) {
// 创建目标文件
String destFileName = f.getName() ;
File destFile = new File(destFolder , destFileName) ;
// 复制文件
copyFile(f , destFile) ;
}
}

public static void copyFile(File srcFile , File destFile) throws IOException {
// 创建流对象
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile)) ;
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile)) ;

// 一次读取一个字节数组复制文件
byte[] bytes = new byte[1024] ;
int len = 0 ;
while((len = bis.read(bytes)) != -1){
bos.write(bytes, 0, len) ;
}
// 释放资源
bos.close() ;
bis.close() ;
}
}

4.9 键盘录入学生信息按照总分排序并写入文本文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public static void main(String[] args) throws IOException {

/**
* 需求:键盘录入3个学生信息(姓名,语文成绩(chineseScore),数学成绩(mathScore),英语成绩(englishScore)),按照总分从高到低存入文本文件
* 分析:
* 1: 创建一个学生类
* 2: 创建一个集合对象TreeSet集合
* 3: 键盘录入学生信息,把学生信息封装到学生对象中,然后把学生对象添加到集合中
* 4: 创建一个高效的字符输出流对象
* 5: 遍历集合,获取每一个元素,把其信息写入到文件中
* 6: 释放资源
*/
// 创建一个集合对象TreeSet集合
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
// 总分
int num = s2.getTotalScore() - s1.getTotalScore() ;
// 比较姓名
int num2 = (num == 0) ? s2.getName().compareTo(s1.getName()) : num ;
// 返回
return num2;
}
}) ;

// 3: 键盘录入学生信息,把学生信息封装到学生对象中,然后把学生对象添加到集合中
for(int x = 1 ; x <= 3 ; x++) {
// 创建Scanner对象
Scanner sc = new Scanner(System.in) ;
System.out.println("请您输入第" + x + "个学生的姓名" );
String sutName = sc.nextLine() ;
System.out.println("请您输入第" + x + "个学生的语文成绩" );
int chineseScore = sc.nextInt() ;
System.out.println("请您输入第" + x + "个学生的数学成绩" );
int mathScore = sc.nextInt() ;
System.out.println("请您输入第" + x + "个学生的英语成绩" );
int englishScore = sc.nextInt() ;

// 把学生的信封装到一个学生对象中
Student s = new Student() ;
s.setName(sutName) ;
s.setMathScore(mathScore) ;
s.setChineseScore(chineseScore) ;
s.setEnglishScore(englishScore) ;
// 把学生的信息添加到集合中
ts.add(s) ;
}

// 创建一个高效的字符输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("student.info")) ;
bw.write("==========================================学生的信息如下====================================================") ;
bw.newLine() ;
bw.flush() ;
bw.write("姓名\t\t总分\t\t数学成绩\t\t语文成绩\t\t英语成绩\t\t") ;
bw.newLine() ;
bw.flush() ;
for(Student t : ts) {
bw.write(t.getName() + "\t\t" + t.getTotalScore() + "\t\t" + t.getMathScore() + "\t\t" + t.getChineseScore() + "\t\t" + t.getEnglishScore()) ;
bw.newLine() ;
bw.flush() ;
}
// 释放资源
bw.close() ;
}

5.IO流大总结【图是摘自网络,感觉很棒】

5.1 按操作方式分类结构图

  • 关于IO流总结如下图所示
  • image

5.2 按操作对象分类结构图

  • 关于IO流总结如下图所示
  • image
-------------本文结束,感谢您的阅读-------------
您的支持将鼓励我继续创作!!