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. mvc core2.1 Identity.EntityFramework Core 登录 (三)

    Controllers->AccountController.cs 新建 [HttpGet] [AllowAnonymous] public async Task<IActionResul ...

  2. (1)HTML的组成(什么是标签、指令、转义字符、数据、标签字符表)

    html的组成:标签+指令+转义字符+数据 1.标签 <>内的,以字母开头,可以结合合法字符(- 或者数字),能被浏览器解析的符号 <!DOCTYPE html> #这个是系统 ...

  3. maven 总结整理(二)——download source code

    当我们用maven下载jar包时,有时希望下载jar包的源代码,此时可以在pom.xml文件中,进行设置. <build>    <finalName>WebProject&l ...

  4. 数学的语言 化无形为可见 (Keith Devlin 著)

    第一章 数字为何靠的住 (已看) 第二章 心智的模式 (已看) 第三章 动静有数 (已看) 第四章 当数学成型 (已看) 第五章 数学揭开美之本质 (已看) 第六章 当数学到位 (已看) 第七章 数学 ...

  5. 微软Azure通知中心 (Azure Notification Hubs)

    Azure Notification Hubs 提供简单的方法从后台(azure或者on-promise)去发送通知在不同的平台上面(iOS, Android, Windows, Kindle, Ba ...

  6. React Native 学习资料

    React Native 学习资料 学习资料 网址 React Native中文网 https://reactnative.cn/

  7. 单页面应用(SPA)重新部署后,正在浏览的页面如何更新缓存?

    当单页面的系统在重新部署更新时,此时正在浏览网页,并且已经在网页内的用户,始终会使用老的js与css文件,一直在使用已经缓存了的静态资源. 所有的缓存问题焦点都在index.html上,只要index ...

  8. 说明os,sys模块不同?并列举常用的模块方法

    官方解释: os: This module provides a portable way of usingoperating system dependent functionality. 翻译:提 ...

  9. Linux 命令之删除命令

    在Linux下删除文件用rm命令,具体用法如下: rm [选项] 文件 选项说明: -f -force 忽略不存在的文件,强制删除,无任何提示 -i --interactive 进行交互式地删除 -r ...

  10. 解决Ecipse和搜狗输入法快捷键冲突问题

    非常简单,关闭掉搜狗输入的所有快捷键!