fileoutputstream-关于java的IO中PrintWriter问题

问题描述

关于java的IO中PrintWriter问题
public class PrintIOTest {
public static void main(String[] ages){
try{
FileOutputStream fos = new FileOutputStream(""test.txt"");
PrintStream ps = new PrintStream(fos);
ps.print(""helloworld!"");

    }catch (FileNotFoundException e){        e.printStackTrace();    }    /*try{        FileWriter fw = new FileWriter(""test.txt"");        PrintWriter pw = new PrintWriter(fw);        pw.write(""你好"");    }catch(IOException e){        e.printStackTrace();    }*/}

}

用字节流外面套一个PrintStream运行正常,但是换成注释里的内容却只能新建test.tex,而不写内容,请问是怎么回事??

解决方案

用这个:
try {
FileWriter fw = new FileWriter(""test.txt"");
PrintWriter pw = new PrintWriter(fw);
pw.write(""你好"");
pw.close();
} catch (IOException e) {
e.printStackTrace();
}

解决方案二:
PrintStream和PrintWriter的区别,参考:http://blog.csdn.net/y3wegy/article/details/8783314

解决方案三:
FileWriter 你需要显式调用 flush 方法。FileWriter 的 close 调用的是其父类 OutputStreamWriter 的 close 方法,其源码如下:
public void close() throws IOException {
se.close();
}
se 是 OutputStreamWriter 对象的私有 StreamEncoder 变量。查看 StreamEncoder 的 close 源码如下:
public void close() throws IOException {
synchronized (lock) {
if (!isOpen)
return;
implClose();
isOpen = false;
}
}
void implClose() throws IOException {
flushLeftoverChar(null true);
try {
for (;;) {
CoderResult cr = encoder.flush(bb);
if (cr.isUnderflow())
break;
if (cr.isOverflow()) {
assert bb.position() > 0;
writeBytes();
continue;
}
cr.throwException();
}
if (bb.position() > 0)
writeBytes();
if (ch != null)
ch.close();
else
out.close();
} catch (IOException x) {
encoder.reset();
throw x;
}
}
在 close 之前先将数据 flush。这就是显式调用 FileWriter 的 close 能够写入数据的原因。
OK,这是 FileWriter 的源码分析。现在来看 PrintStream,你调用的是这个:
public void print(String s) {
if (s == null) {
s = ""null"";
}
write(s);
}
它调用了自己封装的 write 方法:
private void write(String s) {
try {
synchronized (this) {
ensureOpen();
textOut.write(s);
textOut.flushBuffer();
charOut.flushBuffer();
if (autoFlush && (s.indexOf('n') >= 0))
out.flush();
}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
}
它进行了显式 flush,这就是 PrintStream 的 write 不需要显式 flush 的原因。
回过头来再看 FileWriter 的 write 方法,你调用的是其继承自 java.io.Writer 的:
public void write(String str) throws IOException {
write(str 0 str.length());
}
它调用了 java.io.Writer 的:
public void write(String str int off int len) throws IOException {
synchronized (lock) {
char cbuf[];
if (len <= writeBufferSize) {
if (writeBuffer == null) {
writeBuffer = new char[writeBufferSize];
}
cbuf = writeBuffer;
} else { // Don't permanently allocate very large buffers.
cbuf = new char[len];
}
str.getChars(off (off + len) cbuf 0);
write(cbuf 0 len);
}
}
它调用了抽象方法
abstract public void write(char cbuf[] int off int len) throws IOException;
因为你使用 FileWriter,所以它实际上调用的是 OutputStreamWriter 实现的 public void write(char cbuf[] int off int len):
public void write(char cbuf[] int off int len) throws IOException {
se.write(cbuf off len);
}
se(也就是 sun.nio.cs.StreamEncoder) 实现的 write 方法是不自行 flush 的。有其源码为证:
public void write(char cbuf[] int off int len) throws IOException {
synchronized (lock) {
ensureOpen();
if ((off < 0) || (off > cbuf.length) || (len < 0) ||
((off + len) > cbuf.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
implWrite(cbuf off len);
}
}
void implWrite(char cbuf[] int off int len)
throws IOException
{
CharBuffer cb = CharBuffer.wrap(cbuf off len);
if (haveLeftoverChar)
flushLeftoverChar(cb false);
while (cb.hasRemaining()) {
CoderResult cr = encoder.encode(cb bb false);
if (cr.isUnderflow()) {
assert (cb.remaining() <= 1) : cb.remaining();
if (cb.remaining() == 1) {
haveLeftoverChar = true;
leftoverChar = cb.get();
}
break;
}
if (cr.isOverflow()) {
assert bb.position() > 0;
writeBytes();
continue;
}
cr.throwException();
}
}
它使用了字节缓存,在适当的时候才会 flush 一下。
也就是说你 PrintStream 写数据不需要显式 flush,而 FileWriter 写数据需要你显式 flush,不然会有数据丢失。
这下你该明白了吧?

时间: 2024-11-10 00:08:57

fileoutputstream-关于java的IO中PrintWriter问题的相关文章

彻底明白Java的IO系统

转自--豆豆技术网络(http://www.ddvip.net/program/java/index1/61.htm) 一. Input和Output1. stream代表的是任何有能力产出数据的数据源,或是任何有能力接收数据的接收源.在Java的IO中,所有的stream(包括Input和Out stream)都包括两种类型:1.1 以字节为导向的stream以字节为导向的stream,表示以字节为单位从stream中读取或往stream中写入信息.以字节为导向的stream包括下面几种类型:

java的io操作(将字符串写入到txt文件中)_java

复制代码 代码如下: import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.FileWriter;import java.io.IOException;import java.io.PrintStream;import java.io.PrintWriter;import java.io.RandomAccessFile; public cla

java.io中的默认路径是jre所在磁盘根目录么

问题描述 java.io中的默认路径是jre所在磁盘根目录么 如题,File对象中写入相对路径,再显示绝对路径,发现在D:,代码如下.我的jre,eclipse和程序文件夹都在D盘下,但都不在根目录,不知是否java.io中的默认路径都是所在磁盘的根目录. static void p(String s) { System.out.println(s); } public static void main(String[] args) { // TODO Auto-generated method

java.io 中不使用close()方法资源为何cg无法回收?

问题描述 java.io 中不使用close()方法资源为何cg无法回收? 如题,new FileInputStream()新建的文件流都必须要调用close()方法关闭,close方法的介绍是关闭和释放系统资源,并且如果未使用则会资源泄露. 但当指向 FileInputStream()对象的指针离开该对象,CG不是应该回收资源么,用new创建的对象都在栈中,为什么这个FileInputStream()不会自己回收呢? 解决方案 文件流对像不样,不是由虚拟机来掌握的.文件流一般申请的空间是直接到

java网络编程中IO数据输入输出阻塞

问题描述 java网络编程中IO数据输入输出阻塞 服务端代码如下: public class Server { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(30000); Socket socket = ss.accept(); PrintStream ps = new PrintStream(socket.getOutputStream()); ps

Java学习IO篇

        来吧,同志们,为复习网络编程做准备-- 一.理论准备         流是个抽象的概念,是对输入输出设备的抽象,Java程序中,对于数据的输入/输出操作都是以"流"的方式进行,设备可以是文件.网络.内存等.流具有方向性,至于是输入流还是输出流则是一个相对的概念,一般以程序(小马哥说的是机器)为参考,如果数据的流向是程序至设备,我们成为输出流,反之我们称为输入流,可以将流想象成一个"水流管道"(很多资料都这么讲的),自然就出现了方向的概念.      

Java 编程技术中汉字问题的分析及解决(转)

编程|汉字|解决|问题 Java 编程技术中汉字问题的分析及解决 段明辉自由撰稿人2000 年 11月 8日内容: 汉字编码的常识 Java 中文问题的初步认识 Java 中文问题的表层分析及处理 Java 中文问题的根源分析及解决 Java Servlet 中文问题的根源 修改 Servlet.jar 中文乱码的处理函数 参考资料 作者简介在基于 Java 语言的编程中,我们经常碰到汉字的处理及显示的问题.一大堆看不懂的乱码肯定不是我们愿意看到的显示效果,怎样才能够让那些汉字正确显示呢?Jav

Java 编程技术中汉字问题的分析及解决,文件操作

编程|汉字|解决|问题 在基于 Java 语言的编程中,我们经常碰到汉字的处理及显示的问题.一大堆看不懂的 乱码肯定不是我们愿意看到的显示效果,怎样才能够让那些汉字正确显示呢?Java 语言 默认的编码方式是UNICODE ,而我们中国人通常使用的文件和数据库都是基于 GB2312 或者 BIG5 等方式编码的,怎样才能够恰当地选择汉字编码方式并正确地处理汉字的编 码呢?本文将从汉字编码的常识入手,结合 Java 编程实例,分析以上两个问题并提出 解决它们的方案. 现在 Java 编程语言已经广

Java 编程技术中汉字问题的分析及解决(转自IBM)

编程|汉字|解决|问题 Java 编程技术中汉字问题的分析及解决 段明辉自由撰稿人2000 年 11月 8日 在基于 Java 语言的编程中,我们经常碰到汉字的处理及显示的问题.一大堆看不懂的乱码肯定不是我们愿意看到的显示效果,怎样才能够让那些汉字正确显示呢?Java 语言默认的编码方式是UNICODE ,而我们中国人通常使用的文件和数据库都是基于 GB2312 或者 BIG5 等方式编码的,怎样才能够恰当地选择汉字编码方式并正确地处理汉字的编码呢?本文将从汉字编码的常识入手,结合 Java 编