黑马程序员___Java基础[09-IO]

时间:2023-02-18 08:01:44

一、IO流

1、概念

IO流用来处理设备之间的数据传输

Java对数据的操作是通过流的方式

Java用于操作流的类都在IO包中

流按流向分为两种:输入流,输出流。

流按操作类型分为两种:字节流与字符流。  字节流可以操作任何数据,字符流只能操作纯字符数据,比较方便。

2、IO流常用父类

字节流的抽象父类:

InputStream ,OutputStream

字符流的抽象父类:

Reader , Writer

3、IO程序书写

使用前,导入IO包中的类

使用时,进行IO异常处理

使用后,释放资源

二、字节流

1、读取文件

创建FileInputStream对象, 指定一个文件. 文件必须存在, 不存在则会抛出FileNotFoundException

使用read()方法可以从文件中读取一个字节. 如果读取到文件末尾会读到-1

读取结束后需要释放资源, 调用close()方法关闭输入流

2、写出文件

创建FileOutputStream对象, 指定一个文件. 文件不存在会创建新文件, 存在则清空原内容. 如果需要追加, 在构造函数中传入true.

使用write()方法可以向文件写出一个字节.

写出结束后同样需要调用close()

3、拷贝文件

可以从文件中逐个字节读取, 逐个字节写出, 但这样做效率非常低

我们可以定义一个数组作为缓冲区, 一次读取多个字节装入数组, 然后再一次性把数组中的字节写出

4、常用方法

InputStream:

read()   读取一个字节

read(byte[]) 读取若干(数组长度)字节

available()  获取可读的字节数

close()   关闭流, 释放资源

OutputStream:

write(int)  写出一个字节

write(byte[]) 写出数组中的所有字节

write(byte[],start,len);

close()   关闭流, 释放资源

5、BufferedInputStream

BufferedInputStream内置了一个缓冲区(数组)

从BufferedInputStream中读取一个字节时

BufferedInputStream会一次性从文件中读取8192个, 存在缓冲区中, 返回给程序一个

程序再次读取时, 就不用找文件了, 直接从缓冲区中获取

直到缓冲区中所有的都被使用过, 才重新从文件中读取8192个

6、BufferedOutputStream

BufferedOutputStream也内置了一个缓冲区(数组)

程序向流中写出字节时, 不会直接写到文件, 先写到缓冲区中

直到缓冲区写满, BufferedOutputStream才会把缓冲区中的数据一次性写到文件里

三、重点

1、拷贝文件

a、使用FileInputStream和FileOutputStream, 逐个字节拷贝

b、使用FileInputStream和FileOutputStream, 定义一个大数组(length等于文件大小), 一次性拷贝

c、使用FileInputStream和FileOutputStream, 定义一个小数组(例如1024), 多次拷贝

d、使用BufferedInputStream和BufferedOutputStream内置的缓冲区, 逐个字节拷贝

2、标准化IO流操作的代码

a、finally嵌套

b、try close

四、练习

1、从键盘输入接收一个文件路径,把该文件的内容拷贝到工程中

2、从键盘接收输入,把键盘输入的数据写到文件,直到输入quit时退出

五、字符流

1、字符流是什么

字符流是可以直接读写字符的IO流

字节流只能读写字节;如果要读取字符,就要先读取到字节数据,然后转为字符;如果要写出字符,需要把字符转为字节再写出。

2、FileReader, FileWriter

FileReader类的read()方法可以按照字符大小读取

FileWriter类的write()方法可以自动把字符转为字节写出

3、什么情况下使用字符流

字符流也可以拷贝文本文件,但不推荐使用,因为读取时会把字节转为字符,写出时还要把字符转回字节。

程序需要读取一段文本,或者需要写出一段文本的时候可以使用字符流

4、带缓冲的字符流

BufferedReader的read()方法读取字符时会一次读取若干字符到缓冲区,然后逐个返回给程序,降低读取文件的次数,提高效率

BufferedWriter的write()方法写出字符时会先写到缓冲区,缓冲区写满时才会写到文件,降低写文件的次数,提高效率

BufferedReader的readLine()方法可以读取一行字符(不包含换行符号)

BufferedWriter的newLine()可以输出一个跨平台的换行符号

5、LineNumberReader

LineNumberReader是BufferedReader的子类,具有相同的功能,并且可以统计行号

调用getLineNumber()方法可以获取当前行号

调用setLineNumber()方法可以设置当前行号

6、使用指定的码表读取字符

FileReader是使用默认码表读取文件,如果需要使用指定码表读取,那么可以使用InputStreamReader

FileWriter是使用默认码表写出文件,如果需要使用指定码表写出,那么可以使用OutputStreamWriter

六、重点

1、会用BufferedReader读取GBK码表和UTF-8码表的字符

2、会用BufferedWriter写出字符到GBK码表和UTF-8码表的文件中

3、会使用BufferedReader从键盘读取一行

4、会用字节数组拷贝文件,会用BufferedInputStream和BufferedOutputStream拷贝文件

七、File

1、什么是File类

File类对象可以代表一个路径, 此路径可以是文件也可以是文件夹, 该类方法可以对这个路径进行各种操作

2、创建对象

给File类构造函数传一个String类型的路径就可以创建对象

路径分为两种:绝对路径,相对路径

绝对路径:从盘符开始,是一个固定的路径

相对路径:不从盘符开始,相对于某个位置,在Eclipse中的Java工程如果使用相对路径,那么就相对于工程根目录,cmd则相对应于当前目录。

3、常用方法

boolean exists()   判断是否存在

boolean isAbsolute(); 是否是绝对路径

boolean isDirectory(); 是否是文件夹

boolean isFile();  是否是文件

boolean isHidden();  是否是隐藏

 

getAbsolutePath();  获取绝对路径

getFreeSpace();   获取当前盘符剩余空间

getTotalSpace();  获取当前盘符总空间

getUsableSpace();  获取当前盘符可用空间

getParent());   获取父级路径

getName());    获取文件名

 

setReadable(false);  设置是否可读

setWritable(false);  设置是否可写

setExecutable(false); 设置是否可执行

canRead();    是否可读

canWrite();    是否可写

canExecute();   是否可执行

setLastModified();  设置文件的最后修改时间

lastModified();   获取文件的最后修改时间

 

createNewFile()   创建文件

mkdir();    创建文件夹(仅一级)

mkdirs();    创建文件夹(父级不存在也创建)

 

renameTo();    改名, 可以移动文件

delete()    删除, 文件可以直接删除, 文件夹只能删空的

length()    文件大小

 

String[] list() 

File[] listFiles()

4、必须掌握的练习

拷贝文件夹

大家好

一、序列流

1、什么是序列流

序列流可以把多个字节输入流整合成一个,从序列流中读取数据时,将从被整合的第一个流开始读,读完一个之后继续读第二个,以此类推。

2、使用方式

整合两个: SequenceInputStream(InputStream, InputStream)

整合多个: SequenceInputStream(Enumertion)

二、内存输出流

1、什么是内存输出流

该输出流可以向内存中写数据, 把内存当作一个缓冲区, 写出之后可以一次性获取出所有数据

2、使用方式

创建对象: new ByteArrayOutputStream()

写出数据: write(int), write(byte[])

获取数据: toByteArray()

三、对象操作流

1、什么是对象操作流

该流可以将一个对象写出,或者读取一个对象到程序中, 也就是执行了序列化和反序列化的操作。

2、使用方式

写出: new ObjectOutputStream(OutputStream), writeObject()

读取: new ObjectInputStream(InputStream), readObject()

3、注意

要写出的对象必须实现Serializable接口才能被序列化

四、打印流

1、什么是打印流

该流可以很方便的将对象的toString()结果输出, 并且自动加上换行, 而且可以使用自动刷出的模式

System.out就是一个PrintStream, 其默认向控制台输出信息

2、使用方式

打印: print(), println()

自动刷出: PrintStream(OutputStream out, boolean autoFlush, String encoding) 

五、标准输入输出流

1、什么是标准输入输出流

System.in是InputStream, 标准输入流, 默认可以从键盘输入读取字节数据

System.out是PrintStream, 标准输出流, 默认可以向Console中输出字符和字节数据

2、修改标准输入输出流

修改输入流: System.setIn(InputStream)

修改输出流: System.setOut(PrintStream)

六、数据输入输出流

1、什么是数据输入输出流

DataInputStream, DataOutputStream可以按照基本数据类型大小读写数据

例如按Long大小写出一个数字,写出时该数据占8字节,读取的时候也可以按照Long类型读取,一次读取8个字节。

2、使用方式

DataInputStream(InputStream), readInt(), readLong()

DataOutputStream(OutputStream), writeInt(), writeLong()

七、随机读写文件

1、什么是随机读写文件

RandomAccessFile可以对文件执行读和写的操作, 可以将指针移动到任意位置, 在任意位置读写

2、使用方式

创建对象: RandomAccessFile(String, String) 第一个参数是文件路径, 第二个参数是操作模式, 可以是只读或者控制是否使用缓冲区

读取:     read(), readInt(), readDouble()

写出:   write(), writeInt(), writeDouble()

设置文件大小setLength();

移动指针: seek()

八、IO总结

1、字节流

FileInputStream, FileOutputStream, 自定义数组拷贝文件

BufferedInputStream, BufferedOutputStream, 内置缓冲区拷贝文件

2、字符流

FileReader, FileWriter

InputStreamReader, OutputStreamWriter

BufferedReader, BufferedWriter

会读写各种码表的文件中的文本数据

3、File

掌握文件夹递归

拷贝一个带内容的文件夹