1.InputStream

1.1InputStream是所有输入流的超类:

  • int read()

    * 读取下一个字节,并返回字节(0-255)

    * 如果已读到末尾,返回-1

    * read()方法是阻塞(blocking)的,必须等待read()方法返回才能执行下一行代码
  • int read(byte[]):读取若干字节并填充到byte[]数组,返回读取的字节数
  • int read(byte[], int off, int len):指定byte[]数组的偏移量和最大填充术数。
  • void close():关闭输入流
  • 使用try(resource)可以保证InputStream正确关闭

代码一,使用close关闭文件:如果运行时发生IO错误,文件不能正确关闭,资源不能得到及时的释放

  1. public class Main {
  2. public static void main(String[] args) throws IOException {
  3. InputStream input = new FileInputStream("./src/main/java/com/testList/Person.txt");
  4. int n;
  5. while((n=input.read())!= -1){
  6. System.out.println(n);
  7. }
  8. input.close();
  9. }
  10. }

代码二:

  1. public class Main {
  2. public static void main(String[] args) throws IOException {
  3. InputStream input = null;
  4. try{
  5. input= new FileInputStream("./src/main/java/com/testList/Person.txt");
  6. int n;
  7. while((n=input.read())!= -1){
  8. System.out.println(n);
  9. }
  10. }finally {
  11. if (input != null) {
  12. input.close();
  13. }
  14. }
  15. }
  16. }

代码三,使用try(resource)保证InputStream正确关闭,推荐

  1. public class Main {
  2. public static void main(String[] args) throws IOException {
  3. try(InputStream input = new FileInputStream("./src/main/java/com/testList/Person.txt")){
  4. int n;
  5. while((n=input.read())!= -1){
  6. System.out.println(n);
  7. }
  8. }//自动关闭InputStream
  9. }
  10. }

代码四,利用缓冲区一次读取多个字节

  1. public class Main {
  2. public static void main(String[] args) throws IOException {
  3. try(InputStream input = new FileInputStream("./src/main/java/com/testList/Person.txt")){
  4. byte[] buffer = new byte[10];
  5. int n;
  6. while((n=input.read(buffer))!= -1){
  7. System.out.println(Arrays.toString(buffer));
  8. }
  9. }
  10. }
  11. }

1.2常用InputStream

1.2.1 FileInputStream

FileInputStream是InputStream的实现类,可以从文件获取输入流。

  1. try(InputStream input = new FileInputStream("./src/main/java/com/testList/Person.txt")){
  2. byte[] buffer = new byte[10];
  3. int n;
  4. while((n=input.read(buffer))!= -1){
  5. System.out.println(Arrays.toString(buffer));
  6. }

1.2.2 ByteArrayInputStream

ByteArrayInputStream可以在内存中模拟一个InputStream。用的不多,可以测试的时候构造InputStream

  1. public class Main {
  2. public static void main(String[] args) throws IOException {
  3. byte[] data = {-26, -103, -82, -23, -128, -102, -27, -83, -105, -25,-84, -90, -28, -72, -78, 10, 99, 111, 109, 46,116, 101, 115, 116, 76, 105, 115, 116, 46, 77,97, 105, 110, 64, 50, 98, 49, 57, 51, 102,50, 100, 10, 64, 50, 98, 49, 57, 51, 102};
  4. try(InputStream input = new ByteArrayInputStream(data)){
  5. byte[] buffer = new byte[10];
  6. int n;
  7. while((n=input.read(buffer))!= -1){
  8. System.out.println(Arrays.toString(buffer));
  9. }
  10. }
  11. }
  12. }

1.3总结:

  • InputStream定义了所有输入流的超类
  • FileInputStream实现了文件输入
  • ByteArrayInputStream在内存中模拟一个字节流输入
  • 使用try(resource)保证InputStream正确关闭

2.OutputStream

2.1 java.io.OutPutStream是所有输出流的超类:

  • abstract write(int b):写入一个字节
  • void write(byte[] b):写入byte数组的所有字节
  • void write(byte[] b, int off, int len):写入byte[]数组指定范围的字节
  • write()方法是阻塞的,必须等待write方法执行完毕返回后才能执行下一行代码
  • void close():关闭输出流
  • 使用try(resource)可以保证OutputStream正确关闭
  • void flush() :将缓冲区的内容输出

    为什么需要flush呢?

    因为像磁盘、网络写入数据的时候,出于效率的考虑,很多时候,并不是输出1个字节就立即写入。而是先把输出的字节放在内存缓冲区里,等到缓冲区满了之后,再一次性写入。对于很多设备来说,一次写入1个字节和写入1000个字节话费的时间是一样的。所以Output Stream有一个flush方法,能够强制把缓冲区的内容输出。通常情况下,我们不需要调用这个方法,因为缓冲区在满的时候,会自动调用flush。我们在调用close方法关闭OutputStream时,也会调用flush方法。

代码一:如果写入过程中发生IO错误,OutputStream不能正常关闭

  1. public class Main {
  2. public static void main(String[] args) throws IOException {
  3. OutputStream output = new FileOutputStream("./src/main/java/com/testList/output.txt");
  4. output.write(72);//1次写入1个字节
  5. output.write(101);
  6. output.write(108);
  7. output.write(108);
  8. output.write(111);
  9. output.close();
  10. }
  11. }

代码二:通过try(resource)自动关闭文件

  1. public class Main {
  2. public static void main(String[] args) throws IOException {
  3. try(OutputStream output = new FileOutputStream("./src/main/java/com/testList/output.txt")){
  4. output.write(72);
  5. output.write(101);
  6. output.write(108);
  7. output.write(108);
  8. output.write(111);
  9. }
  10. }
  11. }

代码三:一次传入多个字节

  1. public class Main {
  2. public static void main(String[] args) throws IOException {
  3. try(OutputStream output = new FileOutputStream("./src/main/java/com/testList/output.txt")){
  4. byte[] b = "hello,张三".getBytes("UTF-8");
  5. output.write(b,3,9);
  6. }
  7. }
  8. }

代码四:一次性写入

  1. public class Main {
  2. public static void main(String[] args) throws IOException {
  3. try(OutputStream output = new FileOutputStream("./src/main/java/com/testList/output.txt")){
  4. byte[] b = "hello,张三".getBytes("UTF-8");
  5. output.write(b);
  6. }
  7. }
  8. }

2.2 常用OutPutStream:

2.2.1 FileOutStream

FileOutStream可以输出到文件

2.2.2 ByteArrayOutPutStream

ByteArrayOutputStream可以在内存中模拟一个OutputStream

  1. public class Main {
  2. public static void main(String[] args) throws IOException {
  3. try(ByteArrayOutputStream output = new ByteArrayOutputStream()){
  4. output.write("Hello".getBytes("utf-8"));
  5. output.write("world!".getBytes("utf-8"));
  6. byte[] data = output.toByteArray();
  7. System.out.println(Arrays.toString(data));
  8. }
  9. }
  10. }

2.3 总结

  • OutputStream定义了所有输出流的超类
  • FileOutputStream实现了文件流输出
  • ByteArrayOutputStream在内存中模拟一个字节流的输出
  • 使用try(resource)保证OutputStream正确关闭

3.Input/OutPut练习

FileInputStream可以从文件读取数据,FileOutputStream可以把数据写入文件。

如果我们一边从一个文件读取数据,一边把数据写入到另一个文件,就完成了文件的拷贝。

请编写一个程序,接收两个命令行参数,分别表示源文件和目标文件,然后用InputSream/OutputStream把源文件复制到目标文件。

复制后,请检查源文件和目标文件是否相同(文件长度相同,内容相同),分别用文本文件、图片文件和zip文件测试。

使用FileInputStream读取文件

  1. import java.io.File;
  2. import java.io.FileInputStream;
  3. import java.io.IOException;
  4. public class Main {
  5. public static void main(String[] args) throws IOException {
  6. File f = new File("./src/main/java/com/testList/Person.java");
  7. System.out.println(f.length());
  8. //创建字节输入流
  9. FileInputStream fis = new FileInputStream("./src/main/java/com/testList/Person.java");
  10. //创建竹筒
  11. byte[] bbuf = new byte[100];
  12. //保存实际读取的字节数
  13. int hasRead = 0;
  14. //使用循环重复取水过程
  15. while((hasRead = fis.read(bbuf))>0){
  16. //取出竹筒中的水滴即字节,将字节数组转换成字符串输入
  17. System.out.println(new String(bbuf,0,hasRead));
  18. }
  19. //关闭字节流
  20. fis.close();
  21. }
  22. }

使用FileReader读取文件

  1. import java.io.File;
  2. import java.io.FileReader;
  3. import java.io.IOException;
  4. public class Main {
  5. public static void main(String[] args) throws IOException {
  6. File f = new File("./src/main/java/com/testList/Person.java");
  7. System.out.println(f.length());
  8. try(
  9. //创建字符输入流
  10. FileReader fr = new FileReader("./src/main/java/com/testList/Person.java")
  11. ){
  12. //创建一个长度为100的竹筒
  13. char[] cbuf = new char[100];
  14. //hasRead用于保存实际读取的字符数
  15. int hasRead = 0;
  16. while((hasRead =fr.read(cbuf))>0){//使用循环重复取水过程
  17. //取出竹筒中的水滴即字符,将字符数组转换为字符串输入
  18. System.out.println(new String(cbuf,0,hasRead));
  19. }
  20. }catch (IOException ex){
  21. ex.printStackTrace();
  22. }
  23. }
  24. }
  1. import java.io.*;
  2. public class Main {
  3. public static void main(String[] args) throws IOException {
  4. try(
  5. //创建字节输入流
  6. FileInputStream fis = new FileInputStream("./src/main/java/com/testList/Person.java");
  7. //创建字节输出流
  8. FileOutputStream fos = new FileOutputStream("./src/main/java/com/testList/Person.txt")
  9. ){
  10. byte[] bbuf = new byte[300];
  11. int hasRead = 0;
  12. //循环从输入流中取出数据
  13. while ((hasRead = fis.read(bbuf))>0){
  14. //取出1次,写入1次
  15. fos.write(bbuf,0,hasRead);
  16. }
  17. }catch (IOException ex){
  18. ex.printStackTrace();
  19. }
  20. }
  21. }
  1. import java.io.*;
  2. public class Main {
  3. public static void main(String[] args) throws IOException {
  4. try(
  5. //创建字节输出流
  6. FileWriter fw = new FileWriter("./src/main/java/com/testList/Person.txt")
  7. ){
  8. fw.write("于易水送人 - 骆宾王\r\n");
  9. fw.write("此地别燕丹,壮士发冲冠。\r\n");
  10. fw.write("昔时人已没,今日水犹寒。\r\n");
  11. }catch (IOException ex){
  12. ex.printStackTrace();
  13. }
  14. }
  15. }
  1. import java.io.*;
  2. public class Main {
  3. public static void main(String[] args) throws IOException {
  4. try(
  5. FileOutputStream fos = new FileOutputStream("./src/main/java/com/testList/Person.txt");
  6. PrintStream ps = new PrintStream(fos)
  7. ){
  8. ps.println("普通字符串");
  9. ps.println(new Main());
  10. }catch (IOException ex){
  11. ex.printStackTrace();
  12. }
  13. }
  14. }

廖雪峰Java6IO编程-2input和output-1inputStream的更多相关文章

  1. 廖雪峰Java6IO编程-1IO基础-1IO简介

    1.IO简介 IO是指Input/Output,即输入和输出: Input指从外部读取数据到内存,例如从磁盘读取,从网络读取. * 为什么要把数据读到内存才能处理这些数据呢? * 因为代码是在内存中运 ...

  2. 廖雪峰Java15JDBC编程-3JDBC接口-5JDBC连接池

    1. JDBC连接池 1.1 JDBC连接池简介 线程池可以复用一个线程,这样大量的小任务通过线程池的线程执行,就可以避免反复创建线程带来的开销. 同样JDBC可以复用一个JDBC连接 JDBC的连接 ...

  3. 廖雪峰Java15JDBC编程-3JDBC接口-4JDBC事务

    1 数据库事务:Transaction 1.1 定义 若干SQL语句构成的一个操作序列 要么全部执行成功 要么全部执行不成功 1.2 数据库事务具有ACID特性: Atomicity:原子性 一个事务 ...

  4. 廖雪峰Java15JDBC编程-3JDBC接口-3JDBC更新

    使用update语句的时候,需要通过JDBC实现update语句的执行,这个时候仍然通过PreparedStatement对象来使用,直接传入update语句,然后通过setObject传入占位符的值 ...

  5. 廖雪峰Java15JDBC编程-3JDBC接口-2JDBC查询

    我们可以使用JDBC查询来执行select语句. 1. Statement try(Connection conn = DriverManager.getConnection(JDBC_URL, JD ...

  6. 廖雪峰Java15JDBC编程-3JDBC接口-1JDBC简介

    JDBC:Java DataBase Connectivity Java程序访问数据库的标准接口 使用Java程序访问数据库的时候,Java代码并不是直接通过TCP连接去访问数据库,而是通过JDBC接 ...

  7. 廖雪峰Java15JDBC编程-2SQL入门-2insert/select/update/delete

    1. INSERT用于向数据库的表中插入1条记录 insert into 表名 (字段1,字段2,...) values (数据1,数据2,数据3...) 示例 -- 如果表存在,就删除 drop t ...

  8. 廖雪峰Java15JDBC编程-2SQL入门-1SQL介绍

    1.SQL:结构化查询语言 Structured Query Language 针对关系数据库设计 各种数据库基本一致 允许用户通过SQL查询数据而不关心数据库底层存储结构 1.1 SQL使用: 可以 ...

  9. 廖雪峰Java15JDBC编程-1关系数据库基础-1关系数据库简介

    1.数据库 1.1 定义 数据库是按照数据结构来组合.存储和管理数据的软件. 1.2 数据库模型 数据库有层次模型.网状模型.关系模型三种模型. 2 关系数据库 关系数据库是建立在关系模型上的数据库, ...

随机推荐

  1. web四则混合运算2

    一.设计思路: 先出题(String型)(上周已经实现),再写方法计算结果,加入控制有无乘除法,范围,参与计算数,出题数,页码显示等简单功能,有无括号和分数的计算目前还没能实现. 二.代码: 界面 & ...

  2. JAVA中native方法调用

    在Java中native是关键字.它一般在本地声明,异地用C和C++来实现.它的声明有几点要注意:1)native与访问控制符前后的关系不受限制.2)必须在返回类型之前.3)它一般为非抽象类方法.4) ...

  3. (20)模型层 -ORM之msql 基于双下划线的跨表查询(一对一,一对多,多对多)

    基于对象的跨表查询是子查询 基于双下划线的查询是连表查询 PS:基于双下划线的跨表查询 正向按字段,反向按表名小写 一对一 需求:查询lqz这个人的地址# 正向查询ret = models.Autho ...

  4. MySQL系列-优化之like关键字 创建索引

    原文: https://blog.csdn.net/ufo___/article/details/81164996 MySQL系列-优化之覆盖索引:  https://blog.csdn.net/UF ...

  5. AangularJS入门总结三

    (参考的资料) 1. 数据绑定的原理: (1)  $watch 队列: 在DOM中每次绑定一些东西,就会往$watch队列中插入一条$watch: 每一个绑定到了DOM上的数据都会生成一个$watch ...

  6. centos7设置grub密码保护

    设置grub密码保护:查看grub登录用户名cat /etc/grub.d/01_users,可以看到用户名为root.通过grub2-setpasswords设置grub密码,确认密码 cat /b ...

  7. Scala下划线_使用

    下划线这个符号几乎贯穿了任何一本Scala编程书籍,并且在不同的场景下具有不同的含义,绕晕了不少初学者.正因如此,下划线这个特殊符号无形中增加Scala的入门难度.本文希望帮助初学者踏平这个小山坡. ...

  8. 几张简单的terraform flow 图——可以快速了解terraform的使用

    以下是一个简单额terraform flow 我们快速的了解terraform 的使用,基于流程 参考图 参考架构 简单使用流程 说明 从上图我们可以看出terraform 的使用 tf 内容编写 定 ...

  9. sqler sql 转rest api redis 接口使用

    sqler 支持redis 协议,我们可以用过redis client 连接sqler,他会将宏住转换为redis command 实现上看源码我们发现是基于一个开源的redis 协议的golang ...

  10. Spring中时间格式注解@DateTimeFormat

    在SpringMVC中Controller中方法参数为Date类型想要限定请求传入时间格式时,可以通过@DateTimeFormat来指定,但请求传入参数与指定格式不符时,会返回400错误. 如果在B ...