用java中的io流写入文件如何避免覆盖原来的内容?求代码

用java中的io流写入文件如何避免覆盖原来的内容?求代码,第1张

用这个方法public
FileOutputStream(String
name,boolean
append)throws
FileNotFoundException,将逻辑值append设为false时,写入的字节数据覆盖文本原来的内容,为ture是即追加到原来文本的末尾。覆盖原文本内容如:FileOutputStream
x=new
FileOutputStream("文件全路径",false);throws
FileNotFoundException为抛出异常

平时我们使用输入流和输出流一般都会使用buffer包装一下,直接看下面代码(这个代码运行正常,不会报错)

下面我们来研究下这段代码的 bufferedOutputStreamclose(); 方法是否调用了 fileOutputStreamclose();

先看 BufferedOutputStream 源代码:

可以看到它继承 FilterOutputStream ,并且没有重写close方法,所以直接看 FilterOutputStream 的源代码:

跟踪out( FilterOutputStream 中):

再看看 BufferedOutputStream 中:

可以看到 BufferedOutputStream 调用 super(out); ,也就是说, outclose(); 调用的是通过 BufferedOutputStream 传入的被包装的流,这里就是 FileOutputStream 。

我们在看看其他类似的,比如 BufferedWriter 的源代码:

通过观察各种流的源代码,可得结论: 包装的流都会自动调用被包装的流的关闭方法,无需自己调用。

由上面的结论,就会产生一个问题: 如果手动关闭被包装流会怎么样,这个关闭流有顺序吗? 而实际上我们习惯都是两个流都关闭的。

首先我们来做一个简单的实验,基于第一个问题的代码上增加手动增加关闭流的代码,那么就有两种顺序:

上述两种写法都没有问题,我们已经知道 bufferedOutputStreamclose(); 会自动调用 fileOutputStreamclose(); 方法,那么这个方法是怎么执行的呢?我们又看看 FileOutputStream 的源码:

可以看出它采用同步锁,而且使用了关闭标记,如果已经关闭了则不会再次 *** 作,所以多次调用不会出现问题。

如果没有看过参考文章,我可能就会断下结论,关闭流不需要考虑顺序

我们看下下面的代码(修改自参考文章):

会抛出 Stream closed 的IO异常:

而如果把 bwclose(); 放在第一,其他顺序任意,即修改成下面两种:

都不会报错,这是为什么呢,我们立即看看 BufferedWriter 的close源码:

里面调用了 flushBuffer() 方法,也是抛异常中的错误方法:

可以看到很大的一行

这行如果在流关闭后执行就会抛IO异常,有时候我们会写成:

这样也会抛异常,不过是由于 flushBuffer() 中 ensureOpen() 抛的,可从源码中看出:

如何防止这种情况?

直接写下面这种形式就可以:

结论:一个流上的close方法可以多次调用,理论上关闭流不需要考虑顺序,但有时候关闭方法中调用了write等方法时会抛异常。

由上述的两个结论可以得出下面的建议:

关闭流只需要关闭最外层的包装流,其他流会自动调用关闭,这样可以保证不会抛异常。 如:

注意的是,有些方法中close方法除了调用被包装流的close方法外还会把包装流置为null,方便JVM回收。 bwclose() 中的:

finally中就有把out置为null的代码,所以有时候不需要自己手动置为null。(个人建议还是写一下,不差多少执行时间)

1、造成javaioFileNotFoundException异常的原因为:通过io流根据给定路径调用文件时,发现文件不存在。

2、解决办法为:将想要通过io流调用的文件放置到编写程序时给出的对应路径下;或者找到文件,在编写程序时修改io流路径为文件的实际路径。

拓展:

1、Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。

2、Java是由Sun Microsystems公司推出的Java面向对象程序设计语言(以下简称Java语言)和Java平台的总称。由James Gosling和同事们共同研发,并在1995年正式推出。Java最初被称为Oak,是1991年为消费类电子产品的嵌入式芯片而设计的。1995年更名为Java,并重新设计用于开发Internet应用程序。用Java实现的HotJava浏览器(支持Java applet)显示了Java的魅力:跨平台、动态Web、Internet计算。

try{
//read & write
}catch(XXXException e){
//异常处理
}finally{
if(io != null){
ioclose();
}
}
一般将关闭连接,关闭io等 *** 作放在finally,确保一定会被执行。
至于你说不为null时关闭,这个是因为,当io==null时,执行ioclose()会发生空指针异常。
只有io!=null,才能执行ioclose() *** 作。
同样,平时用于判断一个对象是否为空也是需要先判断对象是否为null
如:if(str != null && strtrim()length > 0){//do something}

import javaioBufferedReader;
import javaioBufferedWriter;
import javaioFileReader;
import javaioFileWriter;
import javaioIOException;
public class Test14 {
    public static void main(String[] args) throws IOException {
        String fPath = "C:/testtxt";
        // 读
        BufferedReader br = new BufferedReader(new FileReader(fPath));
        Systemoutprintln(brreadLine());
        brclose();// // 使用后记得关闭
        // 写
        BufferedWriter bw = new BufferedWriter(new FileWriter(fPath));
        bwwrite("写一段话到文件里");
        bwflush();
        bwclose();// 使用后记得关闭
    }
}

Java中的IO流是输入输出流。至于理解,可以将输入和输出两个端点看作是两个工厂,工厂之间需要互相运输货物,而流则是两工厂之间的公路,没有公路就不能互相运输,至于字符,字节和二进制则可以看作是运输的方式和单位大小,比如说把二进制理解成三轮车,那么字节就是小卡车,而字符则是集卡之类的。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/13406801.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-30
下一篇 2023-07-30

发表评论

登录后才能评论

评论列表(0条)

保存