简介
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执行