IO流代表着输入的来源和输出的目的地,如文件,设备,其他程序,内存等
可以有很多类型的数据,如简单的字节,包装过的数据包,本地化过的字符,或者对象
有的流只是传递,有的流可以包装并处理
简单的说,流,就是一个数据的序列
所有的字节流都继承自InputStream和OutputStream,字节流是所有io流的基础
public class CopyBytes { public static void main(String[] args) throws IOException {//一个示例,实际上很少这样用,因为效率太低 FileInputStream in = null; FileOutputStream out = null; try { in = new FileInputStream("xanadu.txt"); out = new FileOutputStream("outagain.txt"); int c; while ((c = in.read()) != -1) {//每次读一个字节 out.write(c); } } finally { if (in != null) {//这一个判断是必须的 in.close(); } if (out != null) { out.close(); } } } }
InputstreamReader和OutputStreamWriter会将底层的字节流包装成字符流
BufferedReader和PrintWriter可以让你一行一行的处理字符 (非字节)
import java.io.FileReader; import java.io.FileWriter; import java.io.BufferedReader; import java.io.PrintWriter; import java.io.IOException; public class CopyLines { public static void main(String[] args) throws IOException { BufferedReader inputStream = null; PrintWriter outputStream = null; try { inputStream = new BufferedReader(new FileReader("xanadu.txt")); outputStream = new PrintWriter(new FileWriter("characteroutput.txt")); String l; while ((l = inputStream.readLine()) != null) {//读取一行 outputStream.println(l);//写入一行 } } finally { if (inputStream != null) { inputStream.close(); } if (outputStream != null) { outputStream.close(); } } } }
BufferedInputStream是从内存中读取数据,直到内存的缓冲区空了,才会调用系统最底层的方式去读取原始字节流,所以效率较高
所以他们的构造方法通常传递一个原始的输入流
BufferedOutputStream则是缓冲区满了才会写入底层
需要的时候,通常要flush
一下,强制传输所有缓存,当然不是缓冲输出流的话调用是无效的
一些额外的构造方法能够让缓冲输出流启用自动flush
功能
有的流能够改变原始流的格式
Scanner能够分离出输入流的各个部分从而单独处理,一般是用空格,tab或回车分隔
s.useDelimiter(",\\s*");//也可以手动更换分隔符
import java.io.*; import java.util.Scanner; public class ScanXan { public static void main(String[] args) throws IOException { Scanner s = null; try { s = new Scanner(new BufferedReader(new FileReader("xanadu.txt"))); while (s.hasNext()) { System.out.println(s.next()); } } finally { if (s != null) { s.close();//Scanner虽然只是处理流,但也是要关闭的,因为它里面有包装的原始输入流 } } } }
s.useLocale(Locale.US);//也可以设置区域,这样数字中也可能会有千位分隔符之类的
但输出时要想正确显示区域,还要用PrintStream
或PrintWriter的format
()方法,将输出流分解
System.out.format("The square root of %d is %f.%n", i, r);//System.out正好是PrintStream类型
除了%%
和 %n
,都需要一个参数,否则会报错
当然print和pirntln也有一点点格式化功能,只是调用他们的toString()而已
InputStreamReader cin = new InputStreamReader(System.in);//跟System.out不同,System.in是个字节流,通常需要包装为字符流
要想跟控制台交互,除了使用System.in,System.out,System.err,还可以使用java.util.Console类:
<pre>import java.io.Console; import java.util.Arrays; import java.io.IOException; public class Password { public static void main (String args[]) throws IOException { Console c = System.console();//这个代表控制台实例 if (c == null) {//null代表没有控制台,有可能是运行方式不允许交互 System.err.println("No console."); System.exit(1); } String login = c.readLine("Enter your login: ");//读取控制台 char [] oldPassword = c.readPassword("Enter your old password: ");//会以*显示,返回的是字符数组而不是String if (verify(login, oldPassword)) { boolean noMatch; do { char [] newPassword1 = c.readPassword("Enter your new password: "); char [] newPassword2 = c.readPassword("Enter new password again: "); noMatch = ! Arrays.equals(newPassword1, newPassword2); if (noMatch) { c.format("Passwords don't match. Try again.%n"); } else { change(login, newPassword1); c.format("Password for %s changed.%n", login);//控制台输出 } Arrays.fill(newPassword1, ' '); Arrays.fill(newPassword2, ' '); } while (noMatch); } Arrays.fill(oldPassword, ' '); }
Data流可以读写各种原始数据类型和String的二进制读写
try { while (true) { price = in.readDouble(); unit = in.readInt(); desc = in.readUTF(); System.out.format("You ordered %d" + " units of %s at $%.2f%n", unit, desc, price); total += unit * price; } } catch (EOFException e) {//但Data输入流判断结束是用异常的 }
Data流有个缺点,内部使用浮点数保存货币值,建议使用java.Math.BigDecimal类型,但却不是原始类型了
需要使用Object Stream
实现了序列化Serializable接口的对象都可以使用对象流,对象流实现的接口是Data流实现的接口的子类
所以所有方法都继续存在
如果readObject()方法没有返回一个期望的对象,试图转换时会报异常ClassNotFound
import java.io.*; import java.math.BigDecimal; import java.util.Calendar; public class ObjectStreams { static final String dataFile = "invoicedata"; static final BigDecimal[] prices = { new BigDecimal("19.99"), new BigDecimal("9.99"), new BigDecimal("15.99"), new BigDecimal("3.99"), new BigDecimal("4.99") }; static final int[] units = { 12, 8, 13, 29, 50 }; static final String[] descs = { "Java T-shirt", "Java Mug", "Duke Juggling Dolls", "Java Pin", "Java Key Chain" }; public static void main(String[] args) throws IOException, ClassNotFoundException { ObjectOutputStream out = null; try { out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(dataFile))); out.writeObject(Calendar.getInstance()); for (int i = 0; i < prices.length; i ++) { out.writeObject(prices[i]); out.writeInt(units[i]); out.writeUTF(descs[i]); } } finally { out.close(); } ObjectInputStream in = null; try { in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(dataFile))); Calendar date = null; BigDecimal price; int unit; String desc; BigDecimal total = new BigDecimal(0); date = (Calendar) in.readObject(); System.out.format ("On %tA, %<tB %<te, %<tY:%n", date); try { while (true) { price = (BigDecimal) in.readObject(); unit = in.readInt(); desc = in.readUTF(); System.out.format("You ordered %d units of %s at $%.2f%n", unit, desc, price); total = total.add(price.multiply(new BigDecimal(unit))); } } catch (EOFException e) {} System.out.format("For a TOTAL of: $%.2f%n", total); } finally { in.close(); } } }
在序列化过程中,同一个序列 (输出流) 只会包含一个对象的唯一一份拷贝
Object ob = new Object(); out.writeObject(ob); out.writeObject(ob);
Object ob1 = in.readObject(); Object ob2 = in.readObject();
读出来仍然是同一个对象
相关推荐
标题"Sourcetrail_2019_4_61_Windows_64bit_Installer.zip"提及的是Sourcetrail的2019年4月61版的64位Windows安装程序。Sourcetrail是一款强大的源代码导航和反编译工具,特别适用于C++和C#等编程语言的开发者。它...
区块链审计追踪 该存储库包含一个分支,在其顶部构建了概念验证的区块链审计跟踪实现。 该区块链审计追踪是我在阿姆斯特丹大学验证审计追踪数据的学士论文的一部分。 该论文的完整版本可,该实现的演示视频可在获得...
目前支持 C、C++、Python 和 ...https://github.com/CoatiSoftware/Sourcetrail/releases 下面简单介绍下如何使用 sourcetrail 阅读源码,以 okhttp 源码为例: 首先打开界面如下,点击左侧的 New Project 创建项目
hybridclr_trial 示例项目 教程在:https://blog.csdn.net/q764424567/article/details/124835067
Oracle审计内容DBA_AUDIT_TRAIL数据字典说明,根据开启的Oracle审计功能,读取dba_audit_trail视图的审计内容包含用户名、操作时间、操作类型、SQL文本、数据库操作次数等等,此文档是对dba_audit_trail视图的中文简介,...
SourceTrail 免费的 C/C++ 代码浏览工具 Linux 版。Sourcetrail is an interactive source explorer that simplifies navigation in existing source code. Sourcetrail's aim is to give answers to all your ...
Rocketseat Ignite开发的汽车租赁应用程序-NodeJS Trail :laptop: 使用: :backhand_index_pointing_right: 磨碎机 :backhand_index_pointing_right: 昂首阔步 :backhand_index_pointing_right: ORM型 :...
Sourcetrail_2019_4_102_Windows_64bit_Installer Sourcetrail_2019_4_102_Windows_64bit_Installer Sourcetrail_2019_4_102_Windows_64bit_Installer Sourcetrail_2019_4_102_Windows_64bit_Installer
《Sourcetrail_2020_1_117_Linux_64bit:源代码导航神器详解》 在IT行业中,高效的代码管理和理解是开发人员至关重要的技能。Sourcetrail,这款名为"Sourcetrail_2020_1_117_Linux_64bit"的软件,便是为了帮助...
audit_trail ='db' db_block_size=8192 db_domain='' db_recovery_file_dest='/u01/app/oracle/fast_recovery_area' db_recovery_file_dest_size=2G diagnostic_de, 这些参数的修改可以根据实际情况进行调整。
说明: 允许数据库管理员指定 PL/SQL 文件 I/O 许可的目录。使用多个 UTL_FILE_DIR 参数即可指定多个目录。请注意所有用户均可读取或写入 UTL_FILE_DIR 参数中指定的所有文件。 值范围: 任何有效的目录路径。 ...
本文将深入探讨名为“SC6138A”的系统级芯片(SoC)所集成的MP3解码器以及其SPDIF输入和I2S输出功能的固件转储,通过标题“EN25T16_20210109_171603 TRAIL 1_frimware_dump_sc6138a_”和描述“sc6138a SOC INBUIT ...
3dMax粒子拖尾光效插件Ky_Trail for max2017-2021下载,安装方法:复制"Ky_Trail.dlv" 到3dMax插件目录( "3dmax\plugins");使用方法:主菜单 -> 渲染 -> 效果 -> 添加 -> Ky_Trail
安装要启用rails_admin_history_rollback ,请将以下内容添加到您的Gemfile确保将其添加到rails_admin之后: gem 'rails_admin'gem 'rails_admin_history_rollback' 不用说,此插件还需要paper_trail gem。...
Sourcetrail_2020_1_117_macOS_64bit.dmg,用于代码阅读,代码分析,可以和很多ide集成,比如idea等。
1. **Cedar Trail**:这是Intel Atom处理器的一个系列,发布于2011年底,主要面向入门级和超便携设备市场。它在前一代(Dell、N450等)的基础上进行了优化,提高了能效并增强了图形处理能力。Cedar Trail平台包括...
1. **连接控制参数**:如DB_BLOCK_SIZE决定了数据块的大小,直接影响I/O性能;INSTANCE_NAME定义实例名,是数据库识别的标识。 2. **内存管理参数**:如SGA_MAX_SIZE设定共享全局区的最大大小,PGA_AGGREGATE_...