目录
1.File类与路径知识
1.File类
2.Java中的路径知识
3.创建File类的实例
4.File类的方法使用
5.File类使用的注意点
2.IO流知识
1.IO流原理
2.文件的读入
3.read()的重载方法:难点
4.文件的写出
1.写出的说明
2.写出操作的具体步骤
5.文件的复制:先读出在写入
6.字节流FileInputStream和FileOutputStream的使用
7.处理流之一:缓冲流
8.处理流之二:转换流
9.标准输入输出流
10.打印流:PrintStream/PrintWriter
11.数据流:DateInputStream/DateOutputStream
12.对象流
13.RandomAccessFile的使用
14.NIO的使用
3.字符集
1.File类与路径知识
1.File的对象可以表示一个文件或文件目录
2.要在java程序中表示一个真实存在的文件或目录,必须有一个File对象,但是java程序中的一个File对象,可能没有一个真实存在的文件或目录。
3.File类声明在java.io包下
1.相对路径:相较于某个路径下指明的路径
2.绝对路径:包含盘符在内的文件路径
3.路径中的每级目录之间用一个路径分隔符隔开
4.路径分隔符和系统有关:
windows和Dos系统默认使用 \ 表示
Unix和URL使用 / 表示
5.IDEA中的路径问题
如果开发中使用JUnit的单元测试方法,相对路径即为当前Module下。
如果开发中使用main方法测试,相对路径即为当前的Project
1.File(String filePath)
2.File(String parentPath,String childPath)
3.File(File parentFile,String childPath)
File file1 = new File("hello.txt");
File file2 = new File("D:\\code\\java", "hi");
File file3 = new File(file2, "h.txt");
此时没有对应文件也不会报错,因为此时只是造了内存层面的几个对象而已。
1.renameTo(File dest):把文件重命名为指定的文件路径:要想返回true,必须file1在硬盘中存在,file2不能存在。
2.getAbsolutePath():获取绝对路径
1.File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法,并未涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容,必须使用IO流来完成。
2.后续File类的对象常会作为参数传递到流的构造器中,指明读取或写入的终点
3.要想删除成功,文件目录下不能有子目录或文件,
2.IO流知识
1.I/O流用于处理设备之间的数据传输;在java中,数据的输入输出操作以流(stream)的方式进行。
2.流的分类
按照数据单位不同:字节流(8 bit),字符流(16bit),一个字符a等于两个字节01
按照流向不同:输入流,输出流
按照流的角色不同:节点流(直接作用在文件上),处理流(包住节点流的流就是处理流)
3.流的体系
1.实例化File类的对象,指明要操作的文件
2.提供具体的流
3.数据的读入:read();返回读入的一个字符,如果达到文件末尾,返回-1;
4.关闭流
代码示例:为突出读入文件的步骤,没有使用try-catch-finally结构,而是throws来处理异常
@Test
public void test2() throws IOException {
//实例化File类的对象,指明要操作的文件
File file = new File("hello.txt");
//2.提供具体的流
FileReader fr = new FileReader(file);
//3.数据的读入:read();返回读入的一个字符,如果达到文件末尾,返回-1;
char[] cbuf = new char[5];
int len;
while ((len = fr.read(cbuf)) != -1) {
for (int i = 0; i < len; i++) {
System.out.print(cbuf[i]);
}
}
//4.关闭流
fr.close();
}
5.为了保证流资源一定执行关闭操作。需要使用try-catch-finally处理
6.读入的文件一定要存在,否则会报FileFoundException。
示例代码:使用try-catch-finally处理异常
@Test
public void testFileReader(){
FileReader fr = null;
try {
//1.实例化File类的对象,指明要操作的文件
File file = new File("hello.txt");
//2.提供具体的流
fr = new FileReader(file);
//3.文件的读入
char[] cbuf = new char[5];
int len;
while ((len = fr.read(cbuf))!= -1){
for (int i = 0;i < len; i++){
System.out.println(cbuf[i]);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fr != null){
//4.关闭流
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
1.read(char[] cbuf):返回每次读入cbuf数组中的个数。如果达到文件末尾,返回-1
2.读入操作的难点:while循环中的len不可血多或血少,否则都无法取得文件中的所有值
//3.数据的读入:read();返回读入的一个字符,如果达到文件末尾,返回-1;
char[] cbuf = new char[5];
int len;
while ((len = fr.read(cbuf)) != -1) {
for (int i = 0; i < len; i++) {
System.out.print(cbuf[i]);
}
}
1.输出操作,对应的File可以不存在。
2.file不存在时,会自动创建文件。
3.若存在,若流使用的构造器是FileWriter(file,false),则覆盖原有文件。
若FileWriter(file,true),则添加在原有文件后
1.提供file的对象,指明写出到的文件
2.提供FileWriter的对象,用于数据的写出
3.写出
4.流的关闭
示例代码:两种处理异常的方式都有
@Test
public void testFileWriter() throws Exception {
//1.提供file的对象,指明写出到的文件
File file = new File("hello.txt");
//2.提供FileWriter的对象,用于数据的写出
FileWriter fw = new FileWriter(file);
//3.写出
fw.write("java");
//4.流的关闭
fw.close();
}
@Test
public void testFileWriterTwo(){
FileWriter fw = null;
try {
//1.提供file的对象,指明写出到的文件
File file = new File("hello.txt");
//2.提供FileWriter的对象,用于数据的写出
fw = new FileWriter(file);
//3.写出
fw.write("java");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fw != null){
//4.流的关闭
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
1.创建File类的对象,指明读入和写出的文件
2.创建输入输出流的对象
3.数据的读入和写出
4.关闭流资源
注意:字符流只能用于文件的复制,不能用于图片的复制。图片需要字节流。
@Test
public void test2() throws IOException {
//1.创建File类的对象,指明读入和写出的文件
File srcfile = new File("hello.txt");
File destfile = new File("hello1.txt");
//2.创建输入输出流的对象
FileReader fr = new FileReader(srcfile);
FileWriter fw = new FileWriter(destfile);
//3.数据的读入和写出
char[] cbuf = new char[5];
int len;//记录每次读入到cbuf数组中的字符的个数
while ((len = fr.read(cbuf)) != -1) {
//每次写出len个字符
fw.write(cbuf,0,len);
}
//4.关闭流
fr.close();
}
1.没有try- catch- finally时
@Test
public void test2() throws IOException {
//实例化File类的对象,指明要操作的文件
File file = new File("hello.txt");
//2.提供具体的流
FileInputStream fis = new FileInputStream(file);
//3.数据的读入:read();返回读入的一个字符,如果达到文件末尾,返回-1;
byte[] buffer = new byte[5];
int len;
while ((len = fis.read(buffer)) != -1) {
for (int i = 0; i < len; i++) {
System.out.print(buffer[i]);
}
}
//4.关闭流
fis.close();
}
2.对于文本文件(txt,java,c,cpp),使用字符流
3.对于非文本文件(.jpg,mp3,mp4,avi,.doc,.ppt),使用字节流
1.处理流:套接在已有的流的基础上
缓冲流的作用:提高文件的读写效率
2.使用步骤:造流时:先造节点流,后造处理流-缓冲流
3.资源关闭时,先关外层的流,在关内层流
4.关闭外层流的同时,内层流也会自动的进行关闭,因此内层流的关闭可以省略。
5.提高读写速度的原因:内部提供了一个缓冲区。
6.使用BufferdReader和BufferedWriter
7.读写方法总结
1.InputStreamReader:字节的输入流转换为字符的输入流
2.OutputStreamWriter:字符的输出流转换为字节的输出流
3.提供了字符流和字节流之间的转换
4.字符集
在造流时,第二个形参指明了字符集,具体使用哪个字符集,取决于文件dbcp.txt保存时使用的字符集。
5.字节输入流到字符输入流
6.将utf-8文件转换为gbk文件
7.编码决定了解码;文件编码的方式,决定了解析时使用的字符集。
1.标准输入流:System.in;键盘输入
2.标准输出流:System.out;控制台输出
1.提供了一系列的print()重载方法;
2.System.out.println:标准打印流从控制台输出;
作用:用于读取或写出基本数据类型的变量或字符串
可以存储和读取基本数据类型或对象的处理流
1.ObjectInputStream:反序列化:将磁盘文件中的对象还原为内存中的一个Java对象。
2.ObjectOutputStream:序列化:把内存中的Java对象保存到磁盘或通过网络传输出去。
3.对象的序列化机制:允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久的保存在磁盘上,或通过网络把这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象。
4.Java对象要想序列化,需要满足两个要求:当前类实现接口:Serializable
当前类提供一个全局常量:serialVersionUID
除了当前类需要实现Serializable接口外,还必须保证其内部所有属性也必须是可序列化的。(默认情况下,基本数据类型可序列化)
5.对象流不能序列化static和transient修饰的成员变量。
1.直接继承于Object类;实现了DateInput和DateOutput接口
2.既可以作为输入流,又可以作为输出流
3.创建实例时需要指定一个mode参数,该参数指定访问模式
4.如果作为输出流时,写出到的文件不存在,则在执行过程中自动创建;如果写出的文件存在,则会对原有文件内容进行覆盖,默认情况下是从头覆盖。
5.通过相关操作,实现插入数据的效果。
6.提供了一个seek(int pos)方法,能够在指定pos位置进行覆盖(插入)
7.这个类可以实现一个多线程断点下载的功能;下载前会建立两个临时文件,一个是与被下载文件大小相同的空文件,一个是记录文件指针的位置文件,每次暂停都会保存上一次的指针,在断点下载时,会继续从上一次的地方下载,从而实现断点下载功能。
1.NiO是从1.4版本引入的一套心IO API,作用相同;但NIO是面向缓冲区的(IO是面向流的)、基于通道的IO操作。NIO可以更加高效的进行文件的读写操作。
2.jdk7对NiO进行了扩展,称为NIO.2
3.字符集
1.ASCII:美国标准信息交换码;一个字节的七位表示一个字符
2.ISO8859-1:欧洲码表,一个字节的八位表示
3.GB2312:中国的中文编码表;最多两个字节编码所有字符
4.GBK:中国的中文编码表升级,融合了更多的中文文字符号,最多两个字节编码
5.Unicode:国际标准码:融合了人类所有字符,为每个字符分配唯一的字符码;所有文字可以用两个字节编码
6.UTF-8:变长的编码方式,可用1-4个字节表示一个字符
7.为什么Unicode无法落地:因为Unicode也用两个字节编码,但如果第一位用0/1来表示一个字节表示一个字符还是两个字节表示一个字符,那就只剩2^15次方个不够用了。因此UTF-8使用变长方式解决此问题,根据前几个字符的改变来决定几个字节表示一个字符。