• 你真的以为了解java.io吗 呕心沥血 绝对干货 别把我移出首页了


    文章结构
    1 flush的使用场景
    2 一个java字节流,inputstream 和 outputstream的简单例子
    3 分别测试了可能抛出java.io.FileNotFoundException,java.io.FileNotFoundException: test (拒绝访问。),java.io.FileNotFoundException: test.txt (系统找不到指定的文件。)的所有场景,你再也不怕java.io异常了
    4 测试了flush的使用场景
    5 给出了flush的源码
    6 提出了自己的两个小疑问
     
    1 flush的有效使用场景
    outputstream中有flush()方法, 而inputstream没有用到缓冲区,对于字节流来说,缓冲区就是一个byte数组,而OutputStream类的flush()却什么也没做,其实flush()是Flushable接口的方法,官方文档的对该方法的注释是“Flushes this output stream and forces any buffered output bytes to be written out.”。OutputStream方法实现了Flushable接口,而又什么也没做,真是让人一头雾水,那么什么时候flush()才有效呢?当OutputStream是BufferedOutputStream时。当写文件需要flush()的效果时,需要需要将FileOutputStream作为BufferedOutputStream构造函数的参数传入,然后对BufferedOutputStream进行写入操作,才能利用缓冲及flush()。查看BufferedOutputStream的源代码,发现所谓的buffer其实就是一个byte[]。BufferedOutputStream的每一次write其实是将内容写入byte[],当buffer容量到达上限时,会触发真正的磁盘写入。而另一种触发磁盘写入的办法就是调用flush()了。
     
    2一个java字节流,inputstream 和 outputstream的简单例子
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    public class OutputStreamDemo {
        public static void main(String[] args) {
              try {
    
                 // create a new output stream
                 OutputStream os = new FileOutputStream("test.txt");
    
                 // craete a new input stream
                 InputStream is = new FileInputStream("test.txt");
                 // write something
                 os.write('A');
    
                 // flush the stream but it does nothing
                 os.flush();
    
                 // write something else
                 os.write('B');
    
                 // read what we wrote
                 System.out.println("" + is.available());
    
              } catch (Exception ex) {
                 ex.printStackTrace();
              }
    
    
           }
    
    }
    说明我们的os.flush()什么也没有做
    其中  OutputStream os = new FileOutputStream("test.txt");将在我们项目下的根文件下建立一个TXT文件,FileOutputStream创建一个向具有指定名称的文件中写入数据的输出文件流。创建一个新 FileDescriptor 对象来表示此文件连接。如果有安全管理器,则用 name 作为参数调用 checkWrite 方法。 如果该文件存在,但它是一个目录,而不是一个常规文件;或者该文件不存在,但无法创建它;抑或因为其他某些原因而无法打开它,则抛出 FileNotFoundException,
    3 测试java.io异常
    当我们的String name定义为一个空字符串的时候 抛出如下异常
    java.io.FileNotFoundException: 
        at java.io.FileOutputStream.open0(Native Method)
        at java.io.FileOutputStream.open(Unknown Source)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at OutputStreamDemo.OutputStreamDemo.main(OutputStreamDemo.java:14)
     
    当我们在根目录下定义一个文件夹也名为test的文件夹时,会抛出如下异常
    java.io.FileNotFoundException: test (拒绝访问。)
        at java.io.FileOutputStream.open0(Native Method)
        at java.io.FileOutputStream.open(Unknown Source)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at OutputStreamDemo.OutputStreamDemo.main(OutputStreamDemo.java:14)
    当我们的FileOutputStream("test.txt");和FileInputStream("test.txt");中的字符串不一致时会出现异常
    java.io.FileNotFoundException: test.txt (系统找不到指定的文件。)
        at java.io.FileInputStream.open0(Native Method)
        at java.io.FileInputStream.open(Unknown Source)
        at java.io.FileInputStream.<init>(Unknown Source)
        at java.io.FileInputStream.<init>(Unknown Source)
        at OutputStreamDemo.OutputStreamDemo.main(OutputStreamDemo.java:17)
    我们这里用了 os.write('A');这里的'A'是int类型的
    4 测试了flush的使用场景
    OutputStream os = new FileOutputStream("test.txt");
    
                 // craete a new input stream
                 InputStream is = new FileInputStream("test.txt");
                 // write something
                 BufferedOutputStream bos = new BufferedOutputStream(os);
                 bos.write('C');
    
                 // flush the stream but it does nothing
                 bos.flush();
    
                 // write something else
                 bos.write('B');
                 bos.close();

    如果我们不使用flush,也不使用close的话,则输出结果为0
    5 给出了flush的源码

    通过查看源码,可以看到 BufferedOutputStream中的flush实现如下 BufferedOutputStream是同步的

    public synchronized void flush() throws IOException {
            flushBuffer();
        out.flush();
        }
    private void flushBuffer() throws IOException {
            if (count > 0) {
            out.write(buf, 0, count);
            count = 0;
            }
        }
        public void write(byte b[], int off, int len) throws IOException {
        if (b == null) {
            throw new NullPointerException();
        } else if ((off < 0) || (off > b.length) || (len < 0) ||
               ((off + len) > b.length) || ((off + len) < 0)) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return;
        }
        for (int i = 0 ; i < len ; i++) {
            write(b[off + i]);
        }
        }

    6 提出了自己的两个小疑问

    我的小疑问:

    1 小疑问 另外,在我使用editplus打开该文件的时候,我任然可以执行java命令重新对该文件进行写入,这让我想到了java的多线程的锁及数据库的锁
    也对,在我用editplus打开该文件的时候仅仅是执行读取得权限,而其他应用程序是可以进行更改的
    2 当我使用java程序更改该文件的时候,我在打开editplus窗口的时候,提示我the file has been modified by another programmer ,do you want to reload it.这说明editplus有一个监视器随时在监视该文件的状态
  • 相关阅读:
    实现类似“添加扩展程序…”的设计时支持
    为什么word2007写的文章不能显示在首页
    (翻译)LearnVSXNow!#4 创建一个带有工具窗的Package
    (翻译)LearnVSXNow!#1 如何开始VSX开发?
    测试Windows live writer 发日志
    (翻译)LearnVSXNow!#3 创建一个带有简单命令的Package
    styleSheetTheme和them
    (翻译)LearnVSXNow!#2 创建一个空的VS Package
    VS 2008 Package 备忘
    通用树形表查询SQL
  • 原文地址:https://www.cnblogs.com/winAlaugh/p/5459654.html
Copyright © 2020-2023  润新知