FileReader和FileWriter源码分析

2024-01-22 01:32

本文主要是介绍FileReader和FileWriter源码分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一:FileWriter


1、类功能简介:


文件字符输出流、主要用于将字符写入到指定的打开的文件中、其本质是通过传入的文件名、文件、或者文件描述符来创建FileOutputStream、然后使用OutputStreamWriter使用默认编码将FileOutputStream转换成Writer(这个Writer就是FileWriter)。如果使用这个类的话、最好使用BufferedWriter包装一下、高端大气上档次、低调奢华有内涵!

2、FileWriter API简介:


A:构造方法

?
1
2
3
4
5
6
7
8
9
FileWriter(File file)   根据给定的 File 对象构造一个 FileWriter 对象。
FileWriter(File file, boolean append)   根据给定的 File 对象构造一个 FileWriter 对象。
FileWriter(FileDescriptor fd)   构造与某个文件描述符相关联的 FileWriter 对象。
FileWriter(String fileName)     根据给定的文件名构造一个 FileWriter 对象。
FileWriter(String fileName, boolean append)     根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。


3、源码分析


?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.chy.io.original.code;
import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.OutputStreamWriter;
/**
  * 文件字符输出流、与国际接轨、创建了此流。
  * 仅仅是提供四个构造方法、还是调用OutputStreamWriter的默认编码的构造方法。
  * 所以FileWriter使用的方法本质都是通过OutputStreamWriter将FileOutputStream传递给StreamEncoder来内部操作字节。给我们展现的则是操作字符。
  */
public class FileWriter extends OutputStreamWriter {
     /**
      * 调用OutputStreamWriter默认编码的构造方法构造FileWriter流。此流是在指定目的地中替换原有内容
      * 从方法也可以看出、是对FileOutputStream的包装。
      */
     public FileWriter(String fileName) throws IOException {
         super ( new java.io.FileOutputStream(fileName));
     }
     /**
      * 调用OutputStreamWriter默认编码创建FileWriter。此流通过传入的append值决定是否目的地中原有内容替换
      */
     public FileWriter(String fileName, boolean append) throws IOException {
         super ( new java.io.FileOutputStream(fileName, append));
     }
     /**
      * 调用OutputStreamWriter默认编码的构造方法构造FileWriter流。此流是在指定目的地中替换原有内容
      */
     public FileWriter(File file) throws IOException {
     super ( new java.io.FileOutputStream(file));
     }
     /**
      * 调用OutputStreamWriter默认编码的构造方法构造FileWriter流。此流通过传入的append值决定是否目的地中原有内容替换
      */
     public FileWriter(File file, boolean append) throws IOException {
         super ( new java.io.FileOutputStream(file, append));
     }
     /**
      * 调用OutputStreamWriter默认编码创建FileWriter。此流通过传入的append值决定是否目的地中原有内容替换
      */
     public FileWriter(FileDescriptor fd) {
         super ( new java.io.FileOutputStream(fd));
     }
}


4、实例演示:


与FileReader结合、简单演示文件拷贝。


二:FileReader


1、类功能简介:


文件字符输入流、用于将文件内容以字符形式读取出来、一般用于读取字符形式的文件内容、也可以读取字节形式、但是因为FileReader内部也是通过传入的参数构造InputStreamReader、并且只能使用默认编码、所以我们无法控制编码问题、这样的话就很容易造成乱码。所以读取字节形式的文件还是使用字节流来操作的好、同样在使用此流的时候用BufferedReader包装一下、就算冲着BufferedReader的readLine()方法去的也要使用这个包装类、不说他还能提高效率、保护存储介质。


2、FileReader API简介:


A:构造方法

?
1
2
3
4
5
FileReader(File file)    在给定从中读取数据的 File 的情况下创建一个新 FileReader。
FileReader(FileDescriptor fd)   在给定从中读取数据的 FileDescriptor 的情况下创建一个新 FileReader。
FileReader(String fileName)     在给定从中读取数据的文件名的情况下创建一个新 FileReader。

3、源码分析


?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.chy.io.original.code;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
/**
  *创建一个文件字符流。本质是用OutputStreamWriter、StreamEncoder对FileInputStream进行装饰。
  *
  * @version     1.1, 13/11/16
  * @author      andyChen
  *
  */
public class FileReader extends InputStreamReader {
    /**
     * 与FileWriter对称、调用父类InputStreamReader默认编码的构造器、及FileInputStream来构造FileReader。
     */
     public FileReader(String fileName) throws FileNotFoundException {
         super ( new FileInputStream(fileName));
     }
    /**
     * 根据File创建一个FileReader
     */
     public FileReader(File file) throws FileNotFoundException {
         super ( new FileInputStream(file));
     }
    /**
     * 根据FileDescriptor创建。
     */
     public FileReader(FileDescriptor fd) {
     super ( new FileInputStream(fd));
     }
}


4、实例演示:


?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package com.chy.io.original.test;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileReaderAndFileWriterTest {
     
     private static File file = new File( "D:" + File.separator + "fw.txt" );
     private static File originalFile = new File( "D:\\j2se7.chm" );
     public static void testFileWriter() throws IOException{
         FileWriter fw = new FileWriter(file);
         
         char [] cbuf = { 0x61 , 0x62 , 0x63 , 0x64 , 0x65 };
         String str = new String(cbuf);
         
         //第一个 “abcde”
         fw.write(cbuf, 0 , cbuf.length);
         fw.write( "\r\n" ); //Windows下插入一个换行符、Linux只需"\n".
         //第二个
         fw.write(cbuf);
         fw.write( "\r\n" );
         //第三个
         for ( char c : cbuf){
             fw.write(c);
         }
         fw.write( "\r\n" );
         //第四个
         fw.write(str);
         fw.write( "\r\n" );
         //第五个
         fw.write(str, 0 , str.length());
         fw.write( "\r\n" );
         //第六个
         fw.append(str, 0 , str.length());
         fw.write( "\r\n" );
         //第七个
         fw.append(str);
         fw.write( "\r\n" );
         //第八个
         for ( char c : cbuf){
             fw.append(c);
         }
         //调用OutputStreamWriter中的flush和close、OutputStreamWriter调用StreamEncoder的这两个方法。
         fw.flush();
         fw.close();
     }
     
     public static void testFileReader() throws IOException{
         FileReader fr = new FileReader(file);
         char [] cbuf = new char [ 5 ];
         fr.read(cbuf, 0 , 5 );
         System.out.println( new String(cbuf));
         fr.skip( 2 );
         fr.read(cbuf);
         System.out.println( new String(cbuf));
         if (!fr.markSupported()){
             System.out.println(fr.markSupported());
             return ;
         }
     }
     
     /**
      * 使用文件字符流copy字节形式的文件
      * 当完成之后去打开copy文件、会提示不能打开此文件、就是因为编码不统一造成了乱码。
      * 我们可以用下面的字节流来实现
      */
     public static void testCopyFileByChar() throws IOException{
         BufferedReader br = new BufferedReader( new FileReader(originalFile));
         
         File targetFile = new File( "E:\\charCopy" + originalFile.getName());
         BufferedWriter bw = new BufferedWriter( new FileWriter(targetFile));
         
         String str ;
         while ((str = br.readLine()) != null ){
             bw.write(str);
         }
         
         br.close();
         bw.flush();
         bw.close();
         System.out.println( "copy success !" );
         
     }
     
     /**
      * 使用字节流copy文件、可以正常使用
      * @throws IOException
      */
     public static void testCopyFileByByte() throws IOException{
         BufferedInputStream bis = new BufferedInputStream( new java.io.FileInputStream(originalFile));
         
         File targetFile = new File( "E:\\byteCopy" + originalFile.getName());
         BufferedOutputStream bos = new BufferedOutputStream( new java.io.FileOutputStream(targetFile));
         
         byte [] b = new byte [ 1024 ];
         int n = 0 ;
         while ((n = bis.read(b)) != - 1 ){
             bos.write(b, 0 , n);
         }
         bis.close();
         bos.flush();
         bos.close();
         System.out.println( "copy success !" );
     }
     
     
     public static void main(String[] args) throws IOException {
         //testFileWriter();
         //testFileReader();
         //testCopyFileByChar();
         testCopyFileByByte();
     }
}


总结:


FileWriter、FileReader以字符的形式对文件进行操作、本质是通过传入的文件名、文件或者文件描述符来创建用于转码或者解码的InputStreamReader、OutputStreamWriter来将对应的FileInputStream、FileOutputStream转换成字符流来操作、但是最好不要乱用、因为使用这两个类的时候我们不能控制编码问题、不同平台、不同环境下的编码不同、当然非要用的话也可以、但是带来的问题还需要去注意、何必呢?像个正常人一样去思考。。。人尽其责、物尽其用!

这篇关于FileReader和FileWriter源码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/631450

相关文章

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

Redis连接失败:客户端IP不在白名单中的问题分析与解决方案

《Redis连接失败:客户端IP不在白名单中的问题分析与解决方案》在现代分布式系统中,Redis作为一种高性能的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景,然而,在实际使用过程中,我们可能... 目录一、问题背景二、错误分析1. 错误信息解读2. 根本原因三、解决方案1. 将客户端IP添加到Re

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步

Redis主从复制实现原理分析

《Redis主从复制实现原理分析》Redis主从复制通过Sync和CommandPropagate阶段实现数据同步,2.8版本后引入Psync指令,根据复制偏移量进行全量或部分同步,优化了数据传输效率... 目录Redis主DodMIK从复制实现原理实现原理Psync: 2.8版本后总结Redis主从复制实

锐捷和腾达哪个好? 两个品牌路由器对比分析

《锐捷和腾达哪个好?两个品牌路由器对比分析》在选择路由器时,Tenda和锐捷都是备受关注的品牌,各自有独特的产品特点和市场定位,选择哪个品牌的路由器更合适,实际上取决于你的具体需求和使用场景,我们从... 在选购路由器时,锐捷和腾达都是市场上备受关注的品牌,但它们的定位和特点却有所不同。锐捷更偏向企业级和专

Spring中Bean有关NullPointerException异常的原因分析

《Spring中Bean有关NullPointerException异常的原因分析》在Spring中使用@Autowired注解注入的bean不能在静态上下文中访问,否则会导致NullPointerE... 目录Spring中Bean有关NullPointerException异常的原因问题描述解决方案总结

python中的与时间相关的模块应用场景分析

《python中的与时间相关的模块应用场景分析》本文介绍了Python中与时间相关的几个重要模块:`time`、`datetime`、`calendar`、`timeit`、`pytz`和`dateu... 目录1. time 模块2. datetime 模块3. calendar 模块4. timeit

python-nmap实现python利用nmap进行扫描分析

《python-nmap实现python利用nmap进行扫描分析》Nmap是一个非常用的网络/端口扫描工具,如果想将nmap集成进你的工具里,可以使用python-nmap这个python库,它提供了... 目录前言python-nmap的基本使用PortScanner扫描PortScannerAsync异