节点流(或文件流)
FileReader
-
FileReader文件字符输入流
-
说明点:
- read()的理解:返回读入的一个字符,如果达到文件末尾,返回-1
- 异常的处理:为了保证流资源一定可以执行关闭操作,需要使用try-catch-finally处理
- 读入的文件一定要存在,否则报FileNotFoundException
-
操作步骤
-
实例化一个File对象File file = new File(“hello2.txt”);指明要操作的文件
-
提供具体的数据流,调用FileReader的构造函数new FileReader(file);
-
数据的读入过程,调用FileReader.read()方法, Returns: The character read, or -1 if the end of the stream has been reached。read()方法返回一个int类型的字符,当返回-1时表示流读取到了文件的末尾。
-
最后,最重要的是,防止内存泄漏,需要将流关闭,fileReader.close()
-
/** * 当hello2.txt文件的内容读入程序中,并输出到控制台 */ @Test public void testFileReader() throws IOException { //1.实例化File类的对象,指明要操作的文件 //相较于当前module File file = new File("hello2.txt"); //2.提供具体的流 if(file.exists()){ FileReader fileReader = null; try { fileReader = new FileReader(file); //3.数据的读入过程 //方式一:read():返回读入的一个字符,如果达到文件末尾,返回-1 int read = fileReader.read(); while(read != -1){ System.out.print((char)read); read = fileReader.read(); } // //方式二:read():返回读入的一个字符,如果达到文件末尾,返回-1 /*int read ; while(( read = fileReader.read()) != -1){ System.out.print((char)read); }*/ } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { //4.流的关闭操作 if(fileReader != null){ try { fileReader.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
-
-
-
FileReader.read(char[])方法的使用
-
read(char[] cbuf):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾返回-1
-
需要注意的点:
- 由于所读取的文件内容不一定就是能整除入参数组长度,也就是最后一次有效读取的字符个数不一定等于入参数组长度。所以在循环输出控制台时,需要使用read(char[] buf)的返回值作为输出个数判断条件
- 也可以使用new String(char value[], int offset, int count)方法,将字符数组的有效部分转成String
-
@Test public void testFileReader1(){ //1.实例化File类的对象,指明要操作的文件 //相较于当前module File file = new File("hello2.txt"); //2.提供具体的流 if(file.exists()){ FileReader fileReader = null; try { fileReader = new FileReader(file); //3.数据的读入过程 //read(char[] cbuf):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾返回-1 int read ; char[] cbuf = new char[5]; while((read = fileReader.read(cbuf)) != -1){ //此处要注意,循环遍历的条件不是数组的长度,因为最后一次读取字符个数不一定就是char[]的长度, // 这样会导致char[]尾部部分字符为上一次读取的字符,所以这里要用read(char[] buf)方法返回的值作为循环条件 for(int i=0;i<read;i++){ System.out.print(cbuf[i]); } //方式二: //System.out.print(new String(cbuf,0,read)); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { //4.流的关闭操作 if(fileReader != null){ try { fileReader.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
-
FileWriter
-
FileWriter文件字符输出流
-
输出操作对应的File不存在,并不会抛出异常
- 如果File对应的硬盘中的文件不存在,在输出的过程中,会自动创建此文件
- 如果File对应的硬盘中的文件存在:
- 如果流的构造器是new FileWriter(File,false)/new File(File):则输出流的操作对原有文件进行覆盖
- 如果流的构造器是new FileWriter(File,true):则输出流不会对原有文件进行覆盖,而是在原有文件的基础上追加内容
-
操作步骤:
-
提供File对象,实例化一个File对象File file = new File(“hello1.txt”),指明要操作的文件
-
提供具体的数据流,调用new FileWriter(file)构造器
-
数据输出过程,调用FileWriter.write(String) ,对文件写入数据
-
最后,最重要的是要关闭流,方式内存泄漏
-
/** * 从内存中写出数据到硬盘的文件里 * 1.输出操作,对应的File可以不存在的,并不会报异常 * 2.File对应的硬盘中的文件如果不存在,在输出的过程中,会自动创建此文件 * File对应的硬盘中的文件如果存在: * 如果流使用的构造器是:FileWriter(file,false)/FileWriter(file):对原有文件的覆盖 * 如果流使用的构造器是:FileWriter(file,true):不会有原有文件覆盖,而是在原有文件基础上追加内容 */ @Test public void testFileWriter(){ //1.提供File类的对象,指明写出到的文件 File file = new File("hello1.txt"); //2.提供具体的流FileWriter FileWriter fileWriter = null; try { fileWriter = new FileWriter(file,true); //3.写出的操作 fileWriter.write("I have a dream!\n"); fileWriter.write("dfasfasdf"); } catch (IOException e) { e.printStackTrace(); }finally { if (fileWriter != null){ try { fileWriter.close(); } catch (IOException e) { e.printStackTrace(); } } } }
-
-
实践:文件流的使用(实现文件的复制)
@Test
public void testCopy(){
//1.创建File的类对象,指明读入和写出的文件
//源文件
File src = new File("hello1.txt");
//目标文件
File dest = new File("helloCopy.txt");
//2.创建输入流、输出流的对象
//文件字符输入流
FileReader fileReader = null;
//文件字符输出流
FileWriter fileWriter = null;
try {
fileReader = new FileReader(src);
fileWriter = new FileWriter(dest);
//单次读取文件长度
char[] cBuf = new char[5];
int length;
//3.1数据的读取
//循环读取文件内容
while((length = fileReader.read(cBuf))!= -1){
//3.2数据的写入
//调用write(char cbuf[], int off, int len) 直接将有效的字符数组输出
fileWriter.write(cBuf,0,length);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.关闭流资源
//关闭文件字符输入流
if(fileReader != null){
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//关闭文件字符输出流
if (fileWriter != null){
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
使用FileInputStream FileOutputStream复制图片
@Test
public void testPicCopy(){
File src = new File("Semaphore.png");
File dest = new File("Semaphore1.png");
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
fileInputStream = new FileInputStream(src);
fileOutputStream = new FileOutputStream(dest);
byte[] bBuf = new byte[1024];
int length;
while((length = fileInputStream.read(bBuf))!= -1){
fileOutputStream.write(bBuf,0,length);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fileInputStream != null){
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fileOutputStream != null){
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
结论
- 对于文本文件(.txt,.java,.c,.cpp),使用字符流处理
- 对于非文本文件(.jpg,.png,.mp3,.mp4,.avi,.doc,.ppt…),使用字节流处理