IO流 打印流 PrintStream System.setOut(ps) 打印100个数换一行

本文深入探讨了PrintWriter和PrintStream在流式输出中的使用方法,包括参数选择、方法调用及错误处理。重点介绍了这两种类如何实现字符与字节的输出,并强调了自动刷新功能的重要性。通过将输出数据保存至指定文件,展示了它们在实际应用中的高效表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

打印流
PrintWriterPrintStream都属于输出流,分别针对字符和字节
PrintWriter和PrintStream提供了重载的print方法
Println方法用于多种数据类型的输出
PrintWriter和PrintStream的输出操作不会抛出异常,用户通过检测错误状态获取错误信息
PrintWriter和PrintStream有自动flush功能

PrintWriter(Writer out)
PrintWriter(Writer out,boolean autoFlush)
PrintWriter(OutputStream out)
PrintWriter(OutputStream out,boolean autoFlush)
PrintStream(OutputStream out)

PrintStream(OutputStream out,boolean autoFlush)



可以看到,dos命令行里面并没有数据,数


据全部被整到d:/bak/log.dat里面了




<think>好的,我现在需要回答用户关于Java中System.in标准输入的底层实现的问题。首先,我得回忆一下System.in的相关知识,可能涉及到Java的IO体系结构。 用户之前已经询问过transient修饰符,现在转向System.in,这说明他们可能在学习Java的基础或IO部分。我需要确保回答准确且易于理解。 首先,System.in是Java的一个静态变量,属于InputStream类型。它通常用于从标准输入(比如控制台)读取数据。但用户问的是底层具体使用的哪个IO,这可能需要深入Java源码或者了解不同平台下的实现差异。 我记得在Java中,System类中的in、out、err都是静态的InputStream或PrintStream类型。对于System.in,其具体实现可能依赖于平台,比如在Windows和Unix-like系统下可能有不同的底层处理。不过,Java通过本地方法(native方法)来与底层系统交互,因此具体的实现可能是在本地代码中。 在标准实现中,比如Oracle JDK或OpenJDK,System.in的初始化可能是在System类初始化时完成的。查看源码的话,可能会发现System.in被初始化为一个FileInputStream,但可能包装了其他类,比如BufferedInputStream。不过这可能因版本而异。 另外,需要注意,当Java程序启动时,标准输入、输出和错误已经由虚拟机创建,通常对应于宿主环境的输入输出设备。例如,在命令行中运行程序时,System.in会读取来自键盘的输入,但也可以通过重定向来从文件或管道读取。 可能需要进一步确认,System.in在底层是否直接对应FileInputStream,或者是否经过缓冲处理。例如,在常见的实现中,System.in可能被包裹在BufferedInputStream中以提高效率,但默认情况下,System.in可能是一个未经缓冲的,因此在实际使用时,开发者通常会将其包装在BufferedReader中。 查阅Java的官方文档,System.in被描述为“标准”输入,这个已经打开并准备提供输入数据。通常,该对应于键盘输入或由主机环境或用户指定的另一个输入源。至于具体的实现,文档可能不会详细说明,因为它依赖于平台和JVM的具体实现。 在OpenJDK的源码中,System类的初始化部分,会调用initializeSystemClass方法,其中会设置in、out、err。对于System.in,其初始化可能涉及到FileInputStream,但具体的文件描述符是标准输入(文件描述符0)。因此,底层可能使用的是FileInputStream,但连接到标准输入的文件描述符上。 不过,考虑到Java的跨平台性,具体的IO实现可能由本地代码处理,Java层只是通过InputStream接口来访问。因此,System.in的具体实现类可能是某个特定的子类,比如FileInputStream或者另一个内部类。 总结起来,System.in在底层可能是一个FileInputStream实例,连接到标准输入的文件描述符(通常是0),但具体的实现可能因JVM和操作系统而异。为了验证这一点,可以编写一个简单的Java程序输出System.in的类名,例如: public class Test { public static void main(String[] args) { System.out.println(System.in.getClass()); } } 运行这个程序可能会得到类似class java.io.BufferedInputStream的结果,或者不同的类名,这取决于具体的JVM实现。例如,在某些环境中,System.in可能被包裹在BufferedInputStream中,而在其他情况下可能直接是FileInputStream。 例如,在Oracle JDK 8中,执行上述代码可能会输出class java.io.BufferedInputStream,说明底层使用了缓冲。但需要确认是否这是标准行为,或者是否因环境而异。 此外,还需要考虑是否在程序中有其他代码修改了System.in,比如通过System.setIn()方法,但默认情况下,它应该是由JVM初始化的标准输入。 因此,最终的回答应该是:System.in的底层实现通常是FileInputStream,连接到标准输入的文件描述符0,但在某些JVM实现中可能会被包装成BufferedInputStream或其他缓冲类,以提升读取效率。具体类名可以通过代码获取,但实际使用时,应将其视为InputStream类型,并根据需要添加缓冲处理。</think>Java的`System.in`标准输入的底层实现依赖于JVM和操作系统,以下是详细说明: --- ### **1. 基本定义** - **类型与作用** `System.in`是`java.io.InputStream`类型的静态变量,用于从标准输入(如键盘、重定向文件)读取数据。 --- ### **2. 底层实现** - **默认实现类** 在Oracle JDK/OpenJDK中,`System.in`的底层通常是**`BufferedInputStream`**,而非直接操作文件描述符。 可通过代码验证: ```java public class Test { public static void main(String[] args) { System.out.println(System.in.getClass()); // 输出示例: class java.io.BufferedInputStream } } ``` - **与文件描述符的关联** `System.in`最终绑定到操作系统的**标准输入文件描述符0**(POSIX标准)。JVM启动时通过本地方法(Native Method)初始化此。 --- ### **3. 实现细节** - **初始化过程** JVM在`System`类初始化时调用`initializeSystemClass()`方法,通过`FileInputStream`包装文件描述符0,并进一步封装为`BufferedInputStream`以提高读取效率。 - **跨平台行为** 具体实现类可能因JVM版本或操作系统不同而略有差异,但逻辑上均指向标准输入源。 --- ### **4. 典型使用场景** - **直接读取控制台输入** 需手动添加缓冲层以提升性能: ```java BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); String input = reader.readLine(); // 读取一行输入 ``` - **重定向输入源** 运行程序时通过命令行重定向输入: ```bash java MyProgram < input.txt ``` --- ### **5. 注意事项** - **不可直接关闭** 调用`System.in.close()`会关闭标准输入,导致后续操作无法读取输入(除非重置)。 **替代方案**:通过`System.setIn(InputStream)`重定向到其他。 - **默认无缓冲** 尽管底层可能是`BufferedInputStream`,但直接使用`System.read()`效率较低,建议包装为`BufferedReader`。 --- ### **6. 总结** `System.in`的底层实现通常为`BufferedInputStream`,封装了操作系统标准输入(文件描述符0)。开发者应通过缓冲类(如`BufferedReader`)高效读取输入,并避免直接关闭此
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值