1.I/O源码分析(3)--BufferedOutputStream之秒懂"flush"
2.javaï¼System.out.println();
3.每日一例 | 更优雅地关闭流(Stream)
4.java中的源码outputstream为什么会乱码呢?
5.Java输出流FileOutputStream的详细使用
I/O源码分析(3)--BufferedOutputStream之秒懂"flush"
本文基于JDK1.8,深入剖析了BufferedOutputStream的源码源码,帮助理解缓冲输出流的源码工作机制。
BufferedOutputStream,源码作为与缓冲输入流相对应的源码面向字节的IO类,其主要功能是源码易语言暴力破解源码通过write方法进行字节写出操作,并在调用flush方法时清除缓存区中的源码剩余字节。
其继承体系主要包括了基本的源码输出流类,如OutputStream。源码
相较于缓冲输入流,源码BufferedOutputStream的源码方法相对较少,但功能同样强大。源码
BufferedOutputStream内部包含两个核心成员变量:buf代表缓冲区,源码count记录缓冲区中可写出的源码字节数。
构造函数默认初始化缓冲区大小为8M,源码若指定大小则按指定大小初始化。
BufferedOutputStream提供了两种主要的写方法:write(int b)用于写出单个字节,以及write(byte[] b, int off, int len)用于从数组中写出指定长度的字节。在内部实现中,使用System.arraycopy函数加速字节的复制过程。
对于上述方法在调用之后,均会进行缓冲区的准 波浪公式源码清空操作,即调用内部的flushBuffer()方法。然而,用户直接调用的公有flush()方法有何意义呢?
在实际应用中,当使用BufferedOutputStream进行高效输出时,用户可能需要在程序结束前调用flush()方法,以确保所有未输出的字节都能被正确处理。避免了在程序未结束时输出流的缓存区中出现未输出的字节。
flush()方法内部逻辑简单,主要通过调用继承自FilterOutputStream的out变量的flush()方法实现缓存区的清空,并将缓冲区的字节全部输出。同时,由于Java的IO流采用装饰器模式,该过程也包括了调用其他实现缓冲功能类的flush方法。
为验证flush()方法的功能,本文进行了简单的测试,通过初始化缓冲区大小为5个字节,分别测试了不调用flush()、调用close()与不调用flush()、不调用close()的情况。
测试结果显示,不调用flush()而调用close()时,好用的ios源码输出为一个特殊符号,表明字节被正确输出。而在不调用flush()且不调用close()的情况下,输出为空,说明有字节丢失。
值得注意的是,如果在测试时定义的字节数组长度超过缓冲区大小,BufferedOutputStream可能直接使用加速机制全部写出,无需调用flush()。
综上所述,使用BufferedOutputStream时,养成在程序结束前调用flush()的习惯,能有效避免因缓存区未清空导致的数据丢失问题,确保程序的稳定性和可靠性。
javaï¼System.out.println();
outæ¯Systemæä¾çç¨äºæ åè¾åºçæµï¼å¨æ²¡æéå®åçæ åµä¸ï¼ä¼ç´æ¥æå°å°ç»ç«¯ï¼èprintlnè¿ä¸ªæ¹å¼å®é ä¸æ¯PrintStreamç±»æä¾çåè½
éå®åé误è¾åºå¨jdkä¸æä¸æ®µè¯´æï¼
é常ï¼æ¤æµå¯¹åºäºæ¾ç¤ºå¨è¾åºæè ç±ä¸»æºç¯å¢æç¨æ·æå®çå¦ä¸ä¸ªè¾åºç®æ ãæç §æ¯ä¾ï¼æ¤è¾åºæµç¨äºæ¾ç¤ºé误æ¶æ¯ï¼æè æ¾ç¤ºé£äºå³ä½¿ç¨æ·è¾åºæµï¼åé out çå¼ï¼å·²ç»éå®åå°é常ä¸è¢«è¿ç»çè§çæä¸æ件æå ¶ä»ç®æ ï¼ä¹åºè¯¥ç«å»å¼èµ·ç¨æ·æ³¨æçå ¶ä»ä¿¡æ¯ã
每日一例 | 更优雅地关闭流(Stream)
在日常编程中,流(Stream)的应用极为广泛,如InputStream/OutPutStream、FileInputStream/FileOutPutStream等。你是否习惯于像下面这样关闭流,或者干脆不进行关闭操作?本文将深入探讨流关闭问题,提供更优雅的视频 api 源码下载解决方案。
通常的关闭方式
让我们先看一段代码示例:
不符合代码质量规范
从逻辑角度看,这似乎是可以接受的,然而,从代码质量和规范性上,它并不达标。使用如sonar或sonarLint插件扫描代码时,会提示存在“Code smell”,推荐采用改进方式。
try-with-resources方式
优化后的代码如下所示:
区别
优化后的代码相较于原始版本更为简洁,主要变化在于将需要在try代码块中使用的资源放于try()中。这种做法实质上是一种语法优化,简化了资源关闭过程,编译器会在编译时自动处理关闭操作,避免了手动关闭资源的繁琐。下面通过反编译代码进一步解析这一变化。
发现新大陆
尽管优化已到位,但为了探究本质差异,我们在close()方法上设置了断点,以观察在不手动关闭资源的情况下,资源是否仍能被自动关闭。
实验结果
首先采用try-with-resources方式,html返回顶部源码发现close方法确实被调用,符合预期。接着,尝试传统写法,同样观察到close方法被调用。然而,更令人好奇的是,在不手动关闭资源的情况下,close方法也成功被调用两次。进一步观察发现,传统写法中,资源在调用close方法后,接着执行了finally块中的关闭操作。
深入分析
在查看FileInputStream的源码时,我们发现创建流时,会将其加入到FileDescriptor中。FileDescriptor中的closeAll方法会循环关闭加入其中的流。然而,这一方法在FileInputStream的close方法中被调用,解释了资源的自动关闭机制。
疑惑与解答
有人疑惑资源是否在非正常情况下不会自动关闭,但实验显示,即使在异常情况下,资源仍会被正确关闭。至于是否是软件自动完成了关闭操作,答案是否定的,进一步调查证实,这与所使用的JDK版本无关。最终,我们认识到,资源的自动关闭与JDK的try-with-resources语句优化密切相关。
总结
本文详细解析了流关闭问题,介绍了优化资源管理的try-with-resources方法,并揭示了资源自动关闭背后的机制。通过深入分析与实验,我们对资源关闭有了更深入的理解,为日常编程提供了更优雅、高效的方法。
java中的outputstream为什么会乱码呢?
dataoutputstream乱码是什么原因呢?不知道的小伙伴来看看小编今天的分享吧!
dataoutputstream乱码的原因:
Java运行环境(JRE)分英文版和国际版,只有国际版才支持非英文字符,如果电脑上装的是英文版,Java开发工具包(JDK)就支持多国字符,但是如果没有按装JDK,直接用压缩包就会出现乱码。
注意:“ Java 源代码- Java 字节码”,标准的 Java 编译器 javac 使用的字符集是系统默认的字符集,比如在中文 Windows 操作系统上就是 GBK ,而在 Linux 操作系统上就是ISO--1,所以开发人员在 Linux 操作系统上编译的类中源文件中的中文字符都出了问题,解决的办法就是在编译的时候添加 encoding 参数,这样才能够与平台无关,用法是 javac –encoding GBK。
dataoutputstream乱码的解决办法:
使用FileOutputStream序列化可以直接向文件写入文本内容,代码如下:
FileOutputStream outStream = new FileOutputStream(file);
outStream.write(str.getBytes());
outStream.close();
但这里的字符串如果包含中文,就会出现乱码,这是因为FileOutputStream是字节流,将文本按字节写入文件,而一个汉字是两个字节,无法一次写入,就会出现乱码,解决方法是使用OutputStreamWriter将字节流转换为字符流写入,同时指定utf-8编码。代码如下:
OutputStreamWriter oStreamWriter = new OutputStreamWriter(new FileOutputStream(file), utf-8);
oStreamWriter.append(str);
oStreamWriter.close();
Java
Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。
Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点。Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等。
Java输出流FileOutputStream的详细使用
上一节描述了如何使用输入流FileInputStream从本地文件读取数据. 本节介绍应用程序输出文件FileOutputStream,以将数据写入本地文件.
使用FileOutputStream写入文件的过程如下:
使用FileOutputStream写入文件的过程与使用FileInputStream的过程相同. 两者都使用File类打开本地文件,实例化输入和输出流,然后调用该流的读写方法以读取或写入数据,最后关闭该流.
FileOutputStream的构造方法
FileOutputStream提供了四种用于实例化FileOutputStream对象的常用构造方法. 在不同的场景中使用不同的构造方法.
场景1: 使用File对象打开本地文件并从文件中读取数据.
场景2: 不使用File对象,而是直接传递文件路径.
FileOutputStream的构造方法允许直接在文件路径中传递而不使用File对象. 查看构造方法的源代码,该方法使用File对象打开文件.
场景3: 打开文件并将数据添加到文件末尾.
场景要求将数据写入文件末尾. 由于前两个构造函数都开始将数据写入文件(覆盖原始文件),因此无法使用前两个场景的构造函数. FileOutputStream分别提供了另外两种构造方法:
FileOutputStream(文件文件,布尔值附加);
FileOutputStream(字符串名称,布尔值附加);
与以前的构造方法相比,这两种构造方法均具有附加的布尔参数附加. 当append参数为true时,将从文件末尾写入数据;否则为false. 当append参数为false时,数据将覆盖原始文件.
FileOutputStream编写方法
FileOutputStream类提供了多种文件写入方法. 您可以单独将字节写入文件,可以将字节数组写入文件,也可以将字节数组数据的一部分写入文件.
示例1: 使用write(int b)方法写入文件.
示例程序首先调用File类的createNewFile()创建new.txt文件,然后将str的内容写入新创建的new.txt文件.
示例2: 使用write(字节[] b)方法写入文件.
The
write(byte [] b)方法用于将b.length个字节从指定的字节数组写入输出流.
String类的getBytes()方法可以将字符串转换为字节数组,并使用FileOutputStream类的write(byte [] b)方法将转换后的字节数组写入文件.
示例3: 使用write(字节[] b,int offfilestream方法参数,int len)方法写入文件.
此方法从数组b的关闭位置开始将len字节的数据写入输出流.
程序将指定的str内容写入文件. fos.write(str.getBytes(),5,)语句的第一个参数是字节数组,第二个参数5是字节数组中的下标. 从5开始,第三个参数是写入的字节数. 程序执行后,写入内容为“是新文件”.
使用此方法时,必须注意数组超出范围的问题. 例如,如果字节数组的长度为(从下标开始),则向文件写入个字节将导致数组越过边界,程序将报告错误.
示例4: 使用FileOutputStream复制文件
复制文件是将源文件数据写入新文件. 在实际编程中filestream方法参数,有很多方法可以复制文件. 在这种情况下,FileInputStream和FileOutputStream用于复制文件.
代码中的copyFile完成文件复制. 复制之前,首先要确定源文件是否存在,然后申请字节数组来存储读取的源文件数据,数组的大小和源文件的总字节数相同,读取成功后,然后将数组的内容写入目标文件. 该程序的输出如下所示:
■知识拨盘
使用FileOutputStream流可以将字节数据写入目标文件. FileOutputStream提供了单字节写入和字节数组写入的两种方式. 建议使用字节数组进行写入,将要写入的数据存储到字节数组中,然后再写入文件. 当写入文件已经存在时,您需要指出写入方法是覆盖还是附加.