简介
FileWriter是读取字符流的类,继承于OutputStreamWriter类,用于将内容通过字符流的方式从应用程序输出到外部文件中
源码分析
OutputStreamWriter
OutputStreamWriter是字节流通向字符流的桥梁,它使用指定的 charset 输出字符并将其编码为字节。
它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。 每次调用 OutputStreamWriter 中的一个 writer() 方法**都会导致**在给定字符上调用编码转换器。生成的字节在写入底层输出流之前在缓冲区中累积。
OutputStreamWriter流的作用就是利用字节流作为底层输出流然后构建字符输出流,字符输出流输出字符到流中,然后通过指定的字符集把流中的字符编码成字节输出到字节流中,其作用就是一个桥梁,使得双方链接起来。
/** Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*********************/package java.io;import java.nio.charset.Charset;import java.nio.charset.CharsetEncoder;import sun.nio.cs.StreamEncoder;/*** An OutputStreamWriter is a bridge from character streams to byte streams:* Characters written to it are encoded into bytes using a specified {@link* java.nio.charset.Charset charset}. The charset that it uses* may be specified by name or may be given explicitly, or the platform's* default charset may be accepted.** <p> Each invocation of a write() method causes the encoding converter to be* invoked on the given character(s). The resulting bytes are accumulated in a* buffer before being written to the underlying output stream. The size of* this buffer may be specified, but by default it is large enough for most* purposes. Note that the characters passed to the write() methods are not* buffered.** <p> For top efficiency, consider wrapping an OutputStreamWriter within a* BufferedWriter so as to avoid frequent converter invocations. For example:** <pre>* Writer out* = new BufferedWriter(new OutputStreamWriter(System.out));* </pre>** <p> A <i>surrogate pair</i> is a character represented by a sequence of two* <tt>char</tt> values: A <i>high</i> surrogate in the range '\uD800' to* '\uDBFF' followed by a <i>low</i> surrogate in the range '\uDC00' to* '\uDFFF'.** <p> A <i>malformed surrogate element</i> is a high surrogate that is not* followed by a low surrogate or a low surrogate that is not preceded by a* high surrogate.** <p> This class always replaces malformed surrogate elements and unmappable* character sequences with the charset's default <i>substitution sequence</i>.* The {@linkplain java.nio.charset.CharsetEncoder} class should be used when more* control over the encoding process is required.** @see BufferedWriter* @see OutputStream* @see java.nio.charset.Charset** @author Mark Reinhold* @since JDK1.1*/public class OutputStreamWriter extends Writer {// 流编码器private final StreamEncoder se;/*** 构造方法* @param out* An OutputStream 字节输出流** @param charsetName* The name of a supported 字符编码集名称* {@link java.nio.charset.Charset charset}**/public OutputStreamWriter(OutputStream out, String charsetName)throws UnsupportedEncodingException{super(out);if (charsetName == null)throw new NullPointerException("charsetName");se = StreamEncoder.forOutputStreamWriter(out, this, charsetName);}/*** 构造方法* @param out An OutputStream 字节输出流*/public OutputStreamWriter(OutputStream out) {super(out);try {se = StreamEncoder.forOutputStreamWriter(out, this, (String)null);} catch (UnsupportedEncodingException e) {throw new Error(e);}}/*** 构造方法* @param out* An OutputStream 字节输出流** @param cs* A charset 字符编码集** @since 1.4* @spec JSR-51*/public OutputStreamWriter(OutputStream out, Charset cs) {super(out);if (cs == null)throw new NullPointerException("charset");se = StreamEncoder.forOutputStreamWriter(out, this, cs);}/*** 构造方法* @param out* An OutputStream 字节输出流** @param enc* A charset encoder 编码器* @since 1.4* @spec JSR-51*/public OutputStreamWriter(OutputStream out, CharsetEncoder enc) {super(out);if (enc == null)throw new NullPointerException("charset encoder");se = StreamEncoder.forOutputStreamWriter(out, this, enc);}/*** 获取当前流的指定编码名称* @return The historical name of this encoding, or possibly* <code>null</code> if the stream has been closed* @revised 1.4* @spec JSR-51*/public String getEncoding() {return se.getEncoding();}/*** 刷新缓存,将缓存中的数据写入流中*/void flushBuffer() throws IOException {se.flushBuffer();}/*** 写入一个字符到流中*/public void write(int c) throws IOException {se.write(c);}/*** 将字符数组off位置后的len个元素通过流输出* @param cbuf Buffer of characters* @param off Offset from which to start writing characters* @param len Number of characters to write** @exception IOException If an I/O error occurs*/public void write(char cbuf[], int off, int len) throws IOException {se.write(cbuf, off, len);}/*** 将字符串中的off位置后len个字符通过流输出* @param str A String* @param off Offset from which to start writing characters* @param len Number of characters to write*/public void write(String str, int off, int len) throws IOException {se.write(str, off, len);}/*** 强刷缓存,将所有缓存中的数据强制输出* @exception IOException If an I/O error occurs*/public void flush() throws IOException {se.flush();}/*** 关闭流,释放资源*/public void close() throws IOException {se.close();}}
可以看到,OutputStreamWriter构造方法主要是结合一个字节输出流和编码集合构建一个StreamEncoder,该编码器可以将字符编码为字节,而后续所有操作都依赖于该类执行。
FileWriter
package java.io;
/**
* @see OutputStreamWriter
* @see FileOutputStream
*
* @author Mark Reinhold
* @since JDK1.1
*/
public class FileWriter extends OutputStreamWriter {
/**
* 构造方法,传入文件名,构造一个文件字节输出流,调用父类方法构造字符输出流
*
* @param fileName String The system-dependent filename.
*/
public FileWriter(String fileName) throws IOException {
super(new FileOutputStream(fileName));
}
/**
* 构造方法,传入文件名和是否追加标识,构造一个文件字节输出流,调用父类方法构造字符输出流
*
* @param fileName String The system-dependent filename.
* @param append boolean if <code>true</code>, then data will be written
* to the end of the file rather than the beginning.
*/
public FileWriter(String fileName, boolean append) throws IOException {
super(new FileOutputStream(fileName, append));
}
/**
* 构造方法,传入文件对象,构造一个文件字节输出流,调用父类方法构造字符输出流
*
* @param file a File object to write to.
*/
public FileWriter(File file) throws IOException {
super(new FileOutputStream(file));
}
/**
* 构造方法,传入文件对象和是否追加标识,构造一个文件字节输出流,调用父类方法构造字符输出流
* @param file a File object to write to
* @param append if <code>true</code>, then bytes will be written
* to the end of the file rather than the beginning
* @since 1.4
*/
public FileWriter(File file, boolean append) throws IOException {
super(new FileOutputStream(file, append));
}
/**
* 构造方法,传入文件描述符,构造一个文件字节输出流,调用父类方法构造字符输出流
* @param fd FileDescriptor object to write to.
*/
public FileWriter(FileDescriptor fd) {
super(new FileOutputStream(fd));
}
}
可见,FileWriter只提供了三个构造方法,其余所有方法都是依赖于父类OutputStreamWriter执行
简单使用
package com.java.io;
import java.io.FileWriter;
import java.io.IOException;
/**
* @description
* @date: 2021-01-19 10:03
*/
public class FileWriterExample {
public static void main(String[] args) {
commonExample();
}
public static void commonExample() {
String filePath = "D:\\IDEAWorkSpace\\JAVALearn\\io\\src\\resource\\fileOut.txt";
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter(filePath);
String message = "只需要看到第五个字符哦";
fileWriter.write(message, 0, 5);
} catch (IOException e) {
e.printStackTrace();
}finally {
if(null!=fileWriter){
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
文件结果:
总结
1、FileWriter是读取字符流的类,继承于OutputStreamWriter类,用于将内容通过字符流的方式从应用程序输出到外部文件中
2、OutputStreamWriter是字节流通向字符流的桥梁,它使用指定的 charset 输出字符并将其编码为字节**。
3、OutputStreamWriter构造方法主要是结合一个字节输出流和编码集合构建一个StreamEncoder,该编码器可以将字符编码为字节,而后续所有操作都依赖于该类执行。
4、FileWriter只提供了三个构造方法,其余所有方法都是依赖于父类OutputStreamWriter执行
