一文让你读懂JAVA.IO、字符编码、URL和Spring.Resource

1 JAVA.IO字节流

一文让你读懂JAVA.IO、字符编码、URL和Spring.Resource

文章插图
 
inputstream.png
  • LineNumberInputStream和StringBufferInputStream官方建议不再使用,推荐使用LineNumberReader和StringReader代替
  • ByteArrayInputStream和ByteArrayOutputStream 字节数组处理流,在内存中建立一个缓冲区作为流使用,从缓存区读取数据比从存储介质(如磁盘)的速率快
//用ByteArrayOutputStream暂时缓存来自其他渠道的数据ByteArrayOutputStream data = https://www.isolves.com/it/cxkf/bk/2020-08-13/new ByteArrayOutputStream(1024); //1024字节大小的缓存区data.write(System.in.read()); // 暂存用户输入数据//将data转为ByteArrayInputStreamByteArrayInputStream in = new ByteArrayInputStream(data.toByteArray());
  • FileInputStream和FileOutputStream 访问文件,把文件作为InputStream,实现对文件的读写操作
  • ObjectInputStream和ObjectOutputStream 对象流,构造函数需要传入一个流,实现对JAVA对象的读写功能;可用于序列化,而对象需要实现Serializable接口
//java对象的写入FileOutputStream fileStream = new FileOutputStream("example.txt");ObjectOutputStream out = new ObjectOutputStream(fileStream);Example example = new Example();out.writeObject(example);//java对象的读取FileInputStream fileStream = new FileInputStream("example.txt");ObjectInputStream in = new ObjectInputStream(fileStream);Example = (Example) in.readObject();
  • PipedInputStream和PipedOutputStream 管道流,适用在两个线程中传输数据,一个线程通过管道输出流发送数据,另一个线程通过管道输入流读取数据,实现两个线程间的数据通信
// 创建一个发送者对象Sender sender = new Sender(); // 创建一个接收者对象Receiver receiver = new Receiver(); // 获取输出管道流// 获取输入输出管道流PipedOutputStream outputStream = sender.getOutputStream(); PipedInputStream inputStream = receiver.getInputStream();// 链接两个管道,这一步很重要,把输入流和输出流联通起来outputStream.connect(inputStream);sender.start();// 启动发送者线程receiver.start();// 启动接收者线程
  • SequenceInputStream 把多个InputStream合并为一个InputStream,允许应用程序把几个输入流连续地合并起来
InputStream in1 = new FileInputStream("example1.txt");InputStream in2 = new FileInputStream("example2.txt");SequenceInputStream sequenceInputStream = new SequenceInputStream(in1, in2);//数据读取int data = https://www.isolves.com/it/cxkf/bk/2020-08-13/sequenceInputStream.read();
  • FilterInputStream和FilterOutputStream 使用了装饰者模式来增加流的额外功能,子类构造参数需要一个InputStream/OutputStream
ByteArrayOutputStream out = new ByteArrayOutputStream(2014);//数据写入,使用DataOutputStream装饰一个InputStream//使用InputStream具有对基本数据的处理能力DataOutputStream dataOut = new DataOutputStream(out);dataOut.writeDouble(1.0);//数据读取ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());DataInputStream dataIn = new DataInputStream(in);Double data = https://www.isolves.com/it/cxkf/bk/2020-08-13/dataIn.readDouble();
  • DataInputStream和DataOutputStream (Filter流的子类) 为其他流附加处理各种基本类型数据的能力,如byte、int、String
  • BufferedInputStream和BufferedOutputStream (Filter流的子类) 为其他流增加缓冲功能
  • PushBackInputStream (FilterInputStream子类) 推回输入流,可以把读取进来的某些数据重新回退到输入流的缓冲区之中
  • PrintStream (FilterOutputStream子类) 打印流,功能类似System.out.print
2 JAVA.IO字符流
一文让你读懂JAVA.IO、字符编码、URL和Spring.Resource

文章插图
 
21.png
  • 从字节流和字符流的导向图来,它们之间是相互对应的,比如CharArrayReader和ByteArrayInputStream
  • 字节流和字符流的转化:InputStreamReader可以将InputStream转为Reader,OutputStreamReader可以将OutputStream转为Writer
//InputStream转为ReaderInputStream inputStream = new ByteArrayInputStream("程序".getBytes());InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);//OutputStream转为WriterOutputStream out = new FileOutputStream("example.txt");OutputStreamWriter writer = new OutputStreamWriter(out);//以字符为单位读写writer.write(reader.read(new char[2]));
  • 区别:字节流读取单位是字节,字符流读取单位是字符;一个字符由字节组成,如变字长编码UTF-8是由1~4个字节表示
3 乱码问题和字符流