JavaSE-IO流

推荐先阅读JavaSE

BufferedInputStream字节缓冲输入流

  • 可以把低级的字节输入流包装成一个高级的缓冲字节输入流管道,从而提高字节输入流读数据的性能。

  • 原理:缓冲字节输入流管道自带了一个8KB的缓冲池,每次可以直接借用操作系统的功能最多提取8KB的数据到缓冲池中去,以后我们直接从缓冲池读取数据,所以性能较好!

  • 高级的字节缓冲流按照一个一个字节数组的形式复制性能极高,建议以后使用!

public BufferedInputStream(InputStream in);

InputStream is = new FileInputStream("Day10Demo/src/dlei04.txt");
BufferedInputStream bis = new BufferedInputStream(is);
byte[] buffer = new byte[3];
int len ;
while((len = is.read(buffer)) != -1){
String rs = new String(buffer, 0 , len);
System.out.print(rs);
}

BufferedOutputStream字节缓冲输出流

public BufferedOutputStream(OutputStream os);

OutputStream os = new FileOutputStream("Day10Demo/src/dlei05.txt");
BufferedOutputStream bos = new BufferedOutputStream(os);
bos.write("我爱中国".getBytes());
bos.close();

FileReader文件字符输入流

public FileReader(File file):创建一个字符输入流与源文件对象接通。
public FileReader(String filePath):创建一个字符输入流与源文件路径接通。

public int read(): 读取一个字符的编号返回! 读取完毕返回-1
Reader fr = new FileReader("Day10Demo/src/dlei01.txt");
int ch ;
while ((ch = fr.read()) != -1){
System.out.print((char)ch);
}

public int read(char[] buffer):读取一个字符数组,读取多少个字符就返回多少个数量,读取完毕返回-1
// a.按照字符数组读取数据使用循环
char[] buffer = new char[1024]; // 1K
// b.定义一个整数记录每次桶读取的字符数据量。
int len;
while((len = fr.read(buffer)) != -1 ) {
// 读取多少倒出多少字符
System.out.print(new String(buffer, 0 , len));
}

FileWriter文件字符输出流

public FileWriter(File file):创建一个字符输出流管道通向目标文件对象。
public FileWriter(String filePath):创建一个字符输出流管道通向目标文件路径。
public FileWriter(File file,boolean append):创建一个追加数据的字符输出流管道通向目标文件对象。
public FileWriter(String filePath,boolean append):创建一个追加数据的字符输出流管道通向目标文件路径。

public void write(int c):写一个字符出去
public void write(String c)写一个字符串出去:
public void write(char[] buffer):写一个字符数组出去
public void write(String c ,int pos ,int len):写字符串的一部分出去
public void write(char[] buffer ,int pos ,int len):写字符数组的一部分出去
// 覆盖数据管道
Writer fw = new FileWriter("Day10Demo/src/dlei03.txt");
// 追加数据管道
Writer fw = new FileWriter("Day10Demo/src/dlei03.txt",true);
// 换行
fw.write("\r\n");

BufferedReader字符缓冲输入流

  • 字符缓冲输入流可以把字符输入流包装成一个高级的缓冲字符输入流, 可以提高字符输入流读数据的性能。
  • 缓冲字符输入流默认会有一个8K的字符缓冲池,可以提高读字符的性能。
public BufferedReader(Reader reader);
public String readLine(): 读取一行数据返回,读取完毕返回null;

Reader fr = new FileReader("Day10Demo/src/dlei06.txt");
BufferedReader br = new BufferedReader(fr);
String line;
while((line = br.readLine())!=null){
System.out.println(line);
}
br.close();

BufferedWriter字符缓冲输出流

public BufferedWriter(Writer writer);
public void newLine():新建一行;

Writer fw = new FileWriter("Day10Demo/src/dlei07.txt",true);
BufferedWriter bw = new BufferedWriter(fw);
bw.write("我在黑马学IO流~~~~");
bw.newLine(); // 换行
bw.write("我在黑马学IO流~~~~");
bw.newLine();// 换行
bw.close();

IO流-InputStreamReader字符输入转换流

可以解决字符流读取不同编码乱码的问题。

可以把原始的字节流按照当前默认的代码编码(或者指定编码)转换成字符输入流。

public InputStreamReader(InputStream is):可以使用当前代码默认编码转换成字符流,几乎不用!
public InputStreamReader(InputStream is,String charset):可以指定编码把字节流转换成字符流

InputStream is = new FileInputStream("D:\\itcast\\网络编程公开课\\Netty.txt");
Reader isr = new InputStreamReader(is,"GBK"); // 指定编码把字节流转换成字符流

IO流-OutputStreamWriter字符输出转换流

public OutputStreamWriter(OutputStream os) :   用当前默认编码UTF-8把字节输出流转换成字符输出流
public OutputStreamWriter(OutputStream os, String charset):指定编码把字节输出流转换成字符输出流

OutputStream os = new FileOutputStream("Day10Demo/src/dlei07.txt");
Writer fw = new OutputStreamWriter(os,"GBK"); // 把字节输出流按照指定编码GBK转换成字符输出流。

IO流-ObjectOutputStream对象序列化流(对象字节输出流)

  • 对象序列化:就是把java对象数据直接存储到文件中去。 对象 => 文件中

  • 对象反序列化:就是把java对象的文件数据恢复到java对象中。 文件中 => 对象

  • 对象必须实现序列化 Serializable 接口 ,才可序列化

  • 如果一个字段不想参数序列化:transient修饰该成员变量,它将不参与序列化!

public ObjectOutputStream(OutputStream out);
public final void writeObject(Object obj); // 序列化方法

User user = new User("tsgz","003197","铁扇公主");
OutputStream os = new FileOutputStream("Day10Demo/src/obj.dat");
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(user);

IO流-ObjectInputStream对象反序列化(对象字节输入流)

  • 序列版本号 private static final long serialVersionUID = 2L;
    必须序列化使用的版本号和反序列化使用的版本号一致才可以正常反序列化!
public ObjectInputStream(InputStream is);
public final Object readObject();

InputStream is = new FileInputStream("Day10Demo/src/obj.dat");
// 2.把字节输入流包装成高的对象字节输入流
ObjectInputStream ois = new ObjectInputStream(is);
// 3.反序列化
User user = (User) ois.readObject();

IO流-PrintStream / PrintWriter打印流

public PrintStream(OutputStream os):
public PrintStream(String filepath):

// PrintStream/PrintWriter 不光可以打印数据,还可以写"字节数据"出去。
PrintStream ps = new PrintStream("Day10Demo/src/dlei08.txt");
PrintWriter pw = new PrintWriter("Day10Demo/src/dlei08.txt");
ps.println(97); // 写97
ps.println(110); // 写110
// 写字节数据出去
ps.write("我爱你".getBytes());

System: public static void setOut(PrintStream out) :让系统的输出流向打印流。
public class PrintStreamDemo02 {
public static void main(String[] args) throws Exception {
System.out.println("==itheima0==");
PrintStream ps = new PrintStream("Day10Demo/src/log.txt");
System.setOut(ps); // 让系统的输出流向打印流。

System.out.println("==itheima1==");
System.out.println("==itheima2==");
System.out.println("==itheima3==");
System.out.println("==itheima4==");
System.out.println("==itheima5==");
}
}

需求:把《出师表》的文章顺序进行恢复到一个新文件中!!

分析:
(1)创建一个缓冲字符输入流对象包装字符输入流接通源文件。
(2)定义一个List集合用于存储每段文章。
(3)定义一个循环按照行读取每段文章,存入到List集合中去。
(4)对List集合中的每个元素按照首字符排序。
(5)创建一个缓冲字符输出流管道通向目标文件。
(6)遍历List集合中的每个元素,通过缓冲字符输出管道写出到目标文件。
(7)释放资源

public class ExecDemo {
public static void main(String[] args) {
try(
// (1)创建一个缓冲字符输入流对象包装字符输入流接通源文件。
BufferedReader br =
new BufferedReader(new FileReader("Day10Demo/src/csb"));
// (5)创建一个缓冲字符输出流管道通向目标文件。
BufferedWriter bw = new BufferedWriter(new FileWriter("Day10Demo/src/newcsb"));
){

// (2)定义一个List集合用于存储每段文章。
List<String> datas = new ArrayList<>();
// (3)定义一个循环按照行读取每段文章,存入到List集合中去。
String line;
while ((line = br.readLine()) != null){
datas.add(line);
}

List<Character> sizes = new ArrayList<>();
Collections.addAll(sizes,'零','一','二','三','四','五','六','七','八','九','十');
// (4)对List集合中的每个元素按照首字符排序。
// Collections.sort(datas, new Comparator<String>() {
// @Override
// public int compare(String s1, String s2) {
// // s1 三.侍中...
// // s2 八.愿陛....
// // indexOf获取元素在List集合中的索引。
// return sizes.indexOf(s1.charAt(0)) - sizes.indexOf(s2.charAt(0));
// }
// });
Collections.sort(datas, ( s1, s2) ->sizes.indexOf(s1.charAt(0)) - sizes.indexOf(s2.charAt(0)));
System.out.println(datas);

// (6)遍历List集合中的每个元素,通过缓冲字符输出管道写出到目标文件。
for (String data : datas) {
bw.write(data);
bw.newLine();
}
}catch (Exception e){
e.printStackTrace();
}
}
}

java.io.File

-- public File(String pathname):根据路径获取文件对象,绝对路径/相对路径
-- public File(String parent , String child):根据父路径和文件名称获取文件对象!
-- public File(File parent , String child)

public String getAbsolutePath() :返回此File的绝对路径名字符串。
public String getPath() : 获取创建文件对象的时候用的路径
public String getName() : 返回由此File表示的文件或目录的名称。
public long length() : 返回由此File表示的文件的长度。

- public boolean exists() :此File表示的文件或目录是否实际存在。
- public boolean isDirectory():此File表示的是否为目录。
- public boolean isFile() :此File表示的是否为文件

- public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,
建一个新的空文件。 (几乎不用的,因为以后文件都是自动创建的!)
- public boolean delete() :删除由此File表示的文件或目录。 (只能删除空目录)
- public boolean mkdir() :创建由此File表示的目录。(只能创建一级目录)
- public boolean mkdirs() :可以创建多级目录(建议使用的)

- public String[] list():获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回。
- public File[] listFiles()(常用):获获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回(重点)
long time = f1.lastModified(); // 最后修改时间!
文件路径分隔符:
-- a.使用正斜杠: /
-- b.使用反斜杠: \\
-- c.使用分隔符API:File.separator