IMG_0413(20220816-161354)

  • 比较基础的是字节流 InputStreamOutputStream

    创建对象要传入路径字符串或者File对象

  • 为了方便读取字符,所以才有了字符流InputStreamReaderOutputStreamWriter

    创建对象要传入字节流对象

    • 转换流的名字比较长,为了简化书写,才有了FileReaderFileWriter。专门处理文本文件。

      创建对象要传入路径字符串

  • 为了更快的读写字节,所以才有了字节缓存流BufferedInputStreamBufferedOutputStream。它只是在字节流上加了缓存效果,

    创建对象需要传入字节流对象

  • 为了更快读取字符,有了字符缓存流BufferedWriterBufferedReader。它是在字符流上加了缓冲效果。

    创建对象要传入字符流对象

File类

三种构造方法:(路径:D:\java.txt)

1
2
3
4
5
6
7
8
9
10
File file = new File("D:\\java.txt");//直接给定路径字符串
System.out.println(file);//D:\java.txt

File file1 = new File("D:\\","java.txt");//父路径字符串+子路径名字符串。
System.out.println(file1);

File file2 = new File("D:\\");
File file3 = new File(file2,"java.txt");//父抽象路径名+子路径字符串
System.out.println(file3);
//这三个构造方法做了同样的事情

常用方法

createNewFile()

如果文件存在,则创建文件再返回true,否则不创建,返回false;

1
2
File file = new File("D:\\JavaText\\test1\\src\\IO流\\File\\itcase\\java2.txt");//将路径封装
System.out.println(file.createNewFile());

mkdir()

创建一个文件夹,类似createNewFile()【注意:即使创建的文件夹名有文件后缀,创建的也是文件夹,比如JAVA.txt文件夹】

1
2
File file1 = new File("D:\\JavaText\\test1\\src\\IO流\\File\\itcase","javaSE");
System.out.println(file1.mkdir());

mkdirs()

创建多级目录

1
2
3
File file2 = new File("D:\\JavaText\\test1\\src\\IO流\\File\\itcase");//父目录
File file3 = new File(file2,"JAVAEE\\javaee\\javaweb");//子目录
System.out.println(file3.mkdirs());

image-20220816162640221

判断方法

1
2
3
4
5
6
7
8
9
10
11
File f = new File("D:\\JavaText\\test1\\src\\JinJie\\day03\\File\\itcast");
System.out.println(f.isDirectory());//isDirectory() 返回此抽象路径名表示的file是否为目录。
System.out.println(f.isFile());//是否是文件
System.out.println(f.isAbsolute());//是否是绝对路径
System.out.println(f.exists());//是否存在
/*
true
false
true
true
*/

获取方法

1
2
3
4
5
6
7
8
9
File file = new File("\\IO流\\File\\itcase");
System.out.println(file.getAbsolutePath());//返回绝对路径
System.out.println(file.getPath());//获取路径 抽象路径--->路径字符串
System.out.println(file.getName());//返回此路径名表示的文件夹名或文件名
/*
D:\IO流\File\itcase
\IO流\File\itcase
itcase
*/

目录遍历

image-20220816162651470

list()

返回该目录下的文件名称字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
File file1 = new File("D:\\JavaText\\test1\\src\\IO流\\File\\itcase");
String[] list = file1.list();//返回该目录下的文件名称字符串
for (String s:list){
System.out.println(s);
}
/*
1.mp4
java.txt
java2.txt
JAVAEE
javaSE
javase.txt
QQ截图20220102223216.png
*/

listFiles()

返回该目录下的文件对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
File file1 = new File("D:\\JavaText\\test1\\src\\IO流\\File\\itcase");
File[] listFiles = file1.listFiles();//返回该目录下的文件对象
for (File file2: listFiles){
System.out.print(file2.getPath()+"\\\\");
if (file2.isFile())System.out.println(file2.getName()+"是文件");
else System.out.println();
}
/*
D:\JavaText\test1\src\IO流\File\itcase\1.mp4\\1.mp4是文件
D:\JavaText\test1\src\IO流\File\itcase\java.txt\\java.txt是文件
D:\JavaText\test1\src\IO流\File\itcase\java2.txt\\java2.txt是文件
D:\JavaText\test1\src\IO流\File\itcase\JAVAEE\\
D:\JavaText\test1\src\IO流\File\itcase\javaSE\\
D:\JavaText\test1\src\IO流\File\itcase\javase.txt\\
D:\JavaText\test1\src\IO流\File\itcase\QQ截图20220102223216.png\\QQ截图20220102223216.png是文件
*/

删除方法

delete()

如果删除文件夹,若此文件夹不是空文件夹,将删除失败。

1
2
3
4
5
6
7
File file = new File("D:\\JavaText\\test1\\src\\JinJie\\day03\\File\\itcast");
//删除文件夹
File file1 = new File(file,"javase.txt");
System.out.println(file1.delete());
//删除文件
File file2 = new File(file,"java.txt");
System.out.println(file2.delete());

IO流

我们把这种数据的传输,可以看做是一种数据的流动,按照流动的方向,以内存为基准,分为 输入input 和 输出 output ,即流向内存是输入流,流出内存的输出流。

根据数据的流向分为:输入流输出流

  • 输入流 :把数据从 其他设备 上读取到 内存 中的流。
  • 输出流 :把数据从 内存 中写出到 其他设备 上的流。

格局数据的类型分为:字节流字符流

  • 字节流 :以字节为单位,读写数据的流。
  • 字符流 :以字符为单位,读写数据的流

字节流

FileOutputStream

FileOutputStream类是文件输出流,用于将数据写出到文件。FileOutputStream继承了OutputStream

构造方法

参数:

  • FileOutputStream(File file) :创建文件输出流以写入由指定的 File对象表示的文件。
  • FileOutputStream(File file, boolean append) :创建文件输出流以写入由指定的 File对象表示的文件。
  • FileOutputStream(String name) :创建文件输出流以指定的名称写入文件。
  • FileOutputStream(String name, boolean append) :创建文件输出流以指定的名称写入文件。

在该路径下

  • 如果没有这个文件,会创建该文件
  • 如果有这个文 件,会清空这个文件的数据
1
2
3
4
//public FileOutputStream(String name)
FileOutputStream fos = new FileOutputStream("D:\\JavaText\\test1\\src\\IO流\\字节流\\java.txt");
//public FileOutputStream(File file)
FileOutputStream fos2 = new FileOutputStream(new File("D:\\JavaText\\test1\\src\\JinJie\\day03\\字节流\\java.txt"));

数据追加续写

public FileOutputStream(File file/String name, boolean append)

参数中需要传入一个boolean类型的值, true 表示追加数据, false 表示清空原有数据。

1
FileOutputStream fos = new FileOutputStream("D:\\JavaText\\test1\\src\\JinJie\\day03\\字节\\java.txt",true);

常用方法

三种写入数据的方法

  • void write(byte[] b) :将 b.length个字节从指定的字节数组写入此文件输出流。
  • void write(byte[] b, int off, int len) :将 len字节从位于偏移量 off的指定字节数组写入此文件输出流。
  • void write(int b) :将指定的字节写入此文件输出流。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Demo1 {
public static void main(String[] args) throws IOException {
//创建文件输出流以指定名称写入文件
FileOutputStream fos = new FileOutputStream("D:\\JavaText\\test1\\src\\IO流\\字节流\\java.txt");

//写字节流的三种方式
//方式一
fos.write(90);//ASCII值
//方式二
fos.write(new byte[]{33,23,67,89});//一次写一个数组的数据
//方式三
fos.write(new byte[]{30,50,60,61,62,63},2,3);//从off开始,写长度为len的数据
fos.close();//关闭此文件输出流并释放资源。
}
}

写入字符串

1
2
String str = "我叫张三!!!";
fos.write(str.getBytes());//getBytes()返回字符串对应的字节数组。

写入换行

1
2
3
4
5
6
7
/*
不同系统识别换行不一样:
Windows:\r\n
linux:\n
mac:\r
*/
fos.write("hello,world!\r\n".getBytes());

FileInputStream

FileInputStream 类是文件输入流,从文件中读取字节。FileInputStream继承了InputStream

构造方法

  • FileInputStream(File file) :通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
  • FileInputStream(String name) :通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。
1
2
FileInputStream fis = new FileInputStream("D:\\JavaText\\test1\\src\\IO流\\字节流");
FileInputStream fis2 = new FileInputStream(new File("D:\\JavaText\\test1\\src\\IO流\\字节流"));

常用方法

  • int read() :从该输入流读取一个字节的数据。
  • int read(byte[] b) :从该输入流读取最多 b.length个字节的数据为字节数组。
  • int read(byte[] b, int off, int len) :从该输入流读取最多 len字节的数据为字节数组。

read 方法,每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回 -1

1
2
3
4
int by;
while ((by=fis.read())!=-1){
System.out.println((char) by);
}

read(byte[] b) ,每次读取b的长度个字节到数组中,返回读取到的有效字节个数读取到末尾时,返回 -1

1
2
3
4
5
6
7
FileInputStream fis = new FileInputStream("D:\\JavaText\\test1\\src\\IO流\\字节流\\java.txt");
byte[] by = new byte[4];
int len;
while ((len=fis.read(by))!=-1){
System.out.println(new String(by,0,len));
}
fis.close();

案例:复制图片

1
2
3
4
5
6
7
8
9
10
11
12
13
public class copyimage {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("C:\\Users\\dell\\Desktop\\QQ截图20220102202037.png");
FileOutputStream fos = new FileOutputStream("D:\\JavaText\\test1\\src\\IO流\\字节流\\image.png");
byte[] by = new byte[1024];
int read;
while ((read = fis.read(by))!=-1){
fos.write(by,0,read);
}
fis.close();
fos.close();
}
}

字符流

当使用字节流读取文本文件时,可能会有一个小问题。就是遇到中文字符时,可能不会显示完整的字符,那是因为一个中文字符可能占用多个字节存储。所以Java提供一些字符流类,以字符为单位读写数据,专门用于处理文本文件

汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数
如果一个汉字存储:

  • 如果是GBK编码,占用2个字节
  • 如果是UTF-8,占用三个字节

字节流操作中文字符不方便
字符流 = 字节流+编码表

OutputStreamWriter

OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集

构造方法

  • OutputStreamWriter(OutputStream out): 创建使用默认字符编码的 OutputStreamWriter
  • OutputStreamWriter(OutputStream out, Charset cs) : 创建使用给定字符集OutputStreamWriter
  • OutputStreamWriter(OutputStream out, CharsetEncoder enc) :创建使用给定字符集编码器OutputStreamWriter
  • OutputStreamWriter(OutputStream out, String charsetName) :创建使用指定字符集OutputStreamWriter
1
2
3
4
5
6
OutputStreamWriter osw = new OutputStreamWriter(
new FileOutputStream("D:\\JavaText\\test1\\src\\JinJie\\day03\\字符流\\java.txt"
),"GBK");
OutputStreamWriter osw = new OutputStreamWriter(
new FileOutputStream("D:\\JavaText\\test1\\src\\IO流\\字符流\\java.txt"
), StandardCharsets.UTF_8);

常用方法

每次调用 write() 方法都会导致在给定字符(或字符集)上调用编码转换器。在写入底层输出流之前,得到的这些字节将在缓冲区中累积。可以指定此缓冲区的大小,不过,默认的缓冲区对多数用途来说已足够大。注意,传递给 write() 方法的字符没有缓冲

  • write(char[] cbuf, int off, int len):写入字符数组的某一部分。
  • write(int c):写入单个字符。
  • write(String str,int off, int len):写入字符串的某一部分。
  • getEncoding():返回此流使用的字符编码的名称。
1
2
3
4
5
osw.write("啦啦啦啦!");
osw.write("我叫田佳澍",2,3);
osw.write(101);
osw.write(new char[]{101,102,103,104});
osw.close();

InputStreamReader

InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

构造方法

InputStreamWriter类似

  • InputStreamReader(InputStream in):创建一个使用默认字符集的 InputStreamReader
  • InputStreamReader(InputStream in, Charset cs) :创建使用给定字符集的 InputStreamReader
  • InputStreamReader(InputStream in, CharsetDecoder dec) :创建使用给定字符集解码器的 InputStreamReader
  • InputStreamReader(InputStream in, String charsetName):创建使用指定字符集的 InputStreamReader
1
2
3
InputStreamReader isr = new InputStreamReader(
new FileInputStream("D:\\JavaText\\test1\\src\\JinJie\\day03\\字符流\\java.txt"),"GBK"
);

常用方法

  • getEncoding() 返回此流使用的字符编码的名称。
  • int read() 读取单个字符。
  • int read(char[] cbuf, int offset, int length) 将字符读入数组中的某一部分。
1
2
3
4
char[] chars = new char[1024];
while ((i=isr.read(chars))!=-1){
System.out.print(new String(chars,0,i));
}

FileReader&FileWriter

便捷字符输入输出流,转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,所以,为了简化书写,转换流提供了对应的子类

  • FileReader:用于读取字符文件的便捷类 继承InputStreamReader 方法一样
    FileReader(String fileName)
  • FileWriter:用于写入字符文件的便捷类 继承OutputStreamWriter 方法一样
    FileWriter(String fileName)

构造时使用系统默认的字符编码和默认字节缓冲区。

案例:复制字符文件

1
2
3
4
5
6
7
8
9
10
11
public static void method() throws IOException{
FileReader fr = new FileReader("D:\\JavaText\\test1\\src\\JinJie\\day01\\Arraysclass.java");
FileWriter fw = new FileWriter("D:\\JavaText\\test1\\src\\JinJie\\day03\\字符流\\copy.java");
int len;
char[] ch = new char[1024];
while ((len=fr.read(ch))!=-1){
fw.write(ch,0,len);
}
fw.close();
fr.close();
}

关闭和刷新

因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件中。但是关闭的流对象,是无法继续写出数据的。如果我们既想写出数据,又想继续使用流,就需要 flush 方法了。

  • flush :刷新缓冲区,流对象可以继续使用。
  • close :先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。
1
2
3
4
5
FileWriter fw = new FileWriter("D:\\JavaText\\test1\\src\\IO流\\字符流\\java.txt");
fw.write("刷新");
fw.flush();
fw.write("关闭");
fw.close();

字节缓冲流

字节缓冲流 **缓冲区大小是默认的,默认值8192**。目的就是加快读取和写入数据的速度

缓冲流本身并没有IO功能,只是在别的流上加上缓冲效果从而提高了效率。当对文件或其他目标频繁读写或操作效率低,效能差时。这时使用缓冲流能够更高效的读写信息。因为缓冲流先将数据缓存起来,然后一起写入或读取出来。所以说,缓冲流还是很重要的,在IO操作时加上缓冲流提升性能。

构造方法

字节缓冲输入流

  • BufferedInputStream(InputStream in) :创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
  • BufferedInputStream(InputStream in, int size) : 创建具有指定缓冲区大小的 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。

字节缓冲输出流

  • BufferedOutputStream(OutputStream out) :创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
  • BufferedOutputStream(OutputStream out, int size) :创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流。
1
2
3
4
5
6
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("D:\\JavaText\\test1\\src\\JinJie\\day03\\字节流\\java.txt")
);
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream("D:\\JavaText\\test1\\src\\JinJie\\day03\\字节流\\java.txt")
);

使用数组缓冲流速度>不使用数组的缓冲流>普通字节流

缓冲流读写方法与基本的流是一致的

字符缓冲流

构造方法

字符缓冲输入流

  • BufferedReader(Reader in) :创建一个使用默认大小输入缓冲区的缓冲字符输入流。
  • BufferedReader(Reader in, int sz) : 创建一个使用指定大小输入缓冲区的缓冲字符输入流。

字符缓冲输出流

  • BufferedWriter(Writer out) :创建一个使用默认大小输出缓冲区的缓冲字符输出流。
  • BufferedWriter(Writer out, int sz) :创建一个使用给定大小输出缓冲区的新缓冲字符输出流。
1
2
3
4
5
6
BufferedWriter bw = new BufferedWriter(
new FileWriter("D:\\JavaText\\test1\\src\\JinJie\\day03\\字符流\\java.txt")
);
BufferedReader br = new BufferedReader(
new FileReader("D:\\JavaText\\test1\\src\\JinJie\\day03\\字符流\\java.txt")
);

特有方法

字符缓冲流的基本方法普通字符流调用方式一致

  • BufferedReader: public String readLine() : 读一行文字。
  • BufferedWriter: public void newLine() : 写一行行分隔符,由系统属性定义符号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void method3() throws IOException{
BufferedReader br = new BufferedReader(
new FileReader("D:\\JavaText\\test1\\src\\JinJie\\day03\\字符流\\Demo1.java")
);
BufferedWriter bw = new BufferedWriter(
new FileWriter("D:\\JavaText\\test1\\src\\JinJie\\day03\\copy.java")
);

String s;
while ((s=br.readLine())!=null){//一次读取一行,不包括任何终止符。如果流已经到末尾,则返回null
bw.write(s);
bw.newLine(); //添加换行符,根据不同系统,换行符不同。
}
bw.close();
br.close();
}

__END__