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

相关文章

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟 开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚 第一站:海量资源,应有尽有 走进“智听

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

MOLE 2.5 分析分子通道和孔隙

软件介绍 生物大分子通道和孔隙在生物学中发挥着重要作用,例如在分子识别和酶底物特异性方面。 我们介绍了一种名为 MOLE 2.5 的高级软件工具,该工具旨在分析分子通道和孔隙。 与其他可用软件工具的基准测试表明,MOLE 2.5 相比更快、更强大、功能更丰富。作为一项新功能,MOLE 2.5 可以估算已识别通道的物理化学性质。 软件下载 https://pan.quark.cn/s/57

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

衡石分析平台使用手册-单机安装及启动

单机安装及启动​ 本文讲述如何在单机环境下进行 HENGSHI SENSE 安装的操作过程。 在安装前请确认网络环境,如果是隔离环境,无法连接互联网时,请先按照 离线环境安装依赖的指导进行依赖包的安装,然后按照本文的指导继续操作。如果网络环境可以连接互联网,请直接按照本文的指导进行安装。 准备工作​ 请参考安装环境文档准备安装环境。 配置用户与安装目录。 在操作前请检查您是否有 sud

线性因子模型 - 独立分量分析(ICA)篇

序言 线性因子模型是数据分析与机器学习中的一类重要模型,它们通过引入潜变量( latent variables \text{latent variables} latent variables)来更好地表征数据。其中,独立分量分析( ICA \text{ICA} ICA)作为线性因子模型的一种,以其独特的视角和广泛的应用领域而备受关注。 ICA \text{ICA} ICA旨在将观察到的复杂信号

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。