关于流的概念

Java 由流来完成具体的IO操作,虽然面对的是不同的外设(网络、鼠标、键盘)IO流使用与全部的外设,在底层Java已经将具体与物理设备交互的细节都处理好了。

流的分类:

从功能上

  输入流:从外部到程序

  输出流:从程序到外部

  注意所谓的输入以及输出是相对于程序而言的,这一点很关键,在流类互相嵌套的时候千万要把握好这一点。

从结构上

  字节流和字符流(字符流实际上是对字节流的封装)

  字节流最低层的两个抽象类是 inputStream 以及 outputStream

  字符流最低层的两个抽象类是 Reader 以及 Writer

还可以有其他的分类方式

  节点流:从特定的地方进行读写的流,直接与目标进行交互。例如从磁盘或者内存的一块区域来进行读写。

  过滤流:使用节点流或者过滤流作为输入或者输出,使用一个已经存在的输入或者是输出创建的流类。

  通常的数据读写的相关逻辑:

  1、 open a stream

  2、 while more information(一边进行读写操作一边进行判断)

  3、 read(write) information

  4、 close information(比较重要 易忽略)

字节流相关

  抽象类inputStream以及outputStream定义了实现其他类的关键方法,最主要的是read以及write方法,两种方法分别在inputStream以及outputStream中被定义,并且被派生类所重写,这些从inputStream与outputStream派生出来的类会针对不同的外设来进行处理。

  三个主要的read方法

  1、abstract int read()

  2、int read(byte[]b)

  3、int read (byte[]b,int offset,int len)

  2,3 两个read 方法通过继承1 的read方法来实现,具体不同的类会有不同的read实现方法。

  FileinputStream的演示(输入流的最一般的组普通的表示形式):

package com.file.fileInputStream;

import java.io.*;

public class fileInputStreamtest {
public static void main(String[] args) throws Exception {
InputStream is = new FileInputStream("F:\\filetest.txt");
// 一次取200个字符
byte[] buffer = new byte[200];
int length;
// read(Byte[]b (字节数组即目标数组),int offset(目标数组起始偏移),int len(每次读取的字字节的长度))
// 注意read方法 要是流已经读完了 就会返回-1 要是没读完就会返回读入buffer的字节数目
while (-1 != (length = is.read(buffer, 0, 200))) {
// 将字符数组转化为子付串
String str = new String(buffer, 0, length);
System.out.println(str); }
// 关闭流
is.close(); } }

这里要注意buffer指定的大小的问题,因为汉字的情况下,按照默认的编码方式(GBK)是两个字节表示一个汉字,要是把buffer的大小设置成一个比较小的奇数比如 3 最后输入汉字的时候 很容易出现乱码,一般把大小设置成1024 2048 这个样子的,都是2的倍数。

字符流inputstream的所有的子类:

AudioInputStream, ByteArrayInputStream, FileInputStream, FilterInputStream, InputStream, ObjectInputStream, PipedInputStream, SequenceInputStream, StringBufferInputStream

字符流outputstream的所有的子类:

ByteArrayOutputStream, FileOutputStream, FilterOutputStream, ObjectOutputStream, OutputStream, PipedOutputStream

字符流中的节点流与过滤流:

节点流 直接与目标文件打交道 比如 FileOutputstream

过滤流 用于对节点流进行包装 减少IO的次数

下面的一个例子是用节点流将数据读入文件再用过滤流将数据从文件中读出:

package com.bytestream.bufferinput;
import java.io.*;
public class bufferTest {
public static void main(String[] args) throws Exception {
OutputStream os=new FileOutputStream("F:\\filetest.txt");
String str="helloworld ";
//将字符串转化为字符数组
byte[]buffer=str.getBytes();
os.write(buffer);
//想要追加内容 后面的true 表示以append的方式进行追加
OutputStream os2=new FileOutputStream("F:\\filetest.txt",true);
String str2="this is added information by append way";
os2.write(str2.getBytes());
os.close();
os2.close(); //利用过滤流 将文件中的内容写入到程序中
InputStream is=new FileInputStream("F:\\filetest.txt");
InputStream bis=new BufferedInputStream(is); byte[]b=new byte[200];
int length;
while(-1!=(length=bis.read(b, 0, 128))){
//注意这里不能使用toString函数 只能是使用newstring生成一个新的string否则会是乱码
//具体的原因还不是太清楚
String bstr1=b.toString();
String bstr2=new String(b,0,length);
System.out.println(bstr1);
System.out.println(bstr2);
} is.close();
bis.close(); } }
输出:
[B@777d57d6
helloworld this is added information by append way

注意直接用toString转化byte数组再打印出来会出现乱码问题

其他的一些过滤流

ByteArrayInputStream以及ByteArrayoutputStream是将字节数组当做源实现输入和输出。

具体例子:

package com.bytestream.ByteArrayinputstreamtest;

import java.io.*;

public class bytearratInputstreamtest {
public static void main(String[] args) throws Exception {
String tmp="the test of bytearraystream";
byte[] b=tmp.getBytes();
ByteArrayInputStream bai=new ByteArrayInputStream(b);
int c;
for(int i=0;i<2;i++){
//采用这种方式是每次读一个字节
while(-1!=(c=bai.read())){
if(i==0)
System.out.print((char)c);
else
//只能是英文情况下
System.out.print(Character.toUpperCase((char)c));
} //将一个流重读了一次 默认指向流最开始的位置
//相当于将bai流重置了 要是不加这个 即使设置了循环两次也还是无效的
bai.reset();
System.out.println();
}
bai.close(); //利用bytearrayoutput将信息写入一个字符串 再利用fileoutputstream将信息写入
//注意与FileOutputStream区别 这个写入的目标对象是一个字符串而不是一个文件
ByteArrayOutputStream bao=new ByteArrayOutputStream();
String strout="test the ByteArrayOutputStream";
//将strout中的内容写入到这个ByteArayOutputStream输出流当中
//这个ByteArrayoutputstream中此时就已经存放了strout的信息 bao.write(strout.getBytes());
//将输出流转化成一个数组对象
byte[]result=bao.toByteArray();
for(int i=0;i<result.length;i++){
System.out.print((char)result[i]);
} OutputStream os=new FileOutputStream("F:\\filetest.txt");
//将ByteArrayOutputstream中的内容写入到一个文件输出流当中
bao.writeTo(os); os.close();
bao.close(); }
} 输出结果:
the test of bytearraystream
THE TEST OF BYTEARRAYSTREAM
test the ByteArrayOutputStream
对应的文件中(F:\filetest.txt)也有了对应的信息

DataInputStream和DataOutputStream可以写入或者写出多种不同的数据类型的数据

package com.bytestream.DataStream;

import java.io.*;

public class DataStream {
public static void main(String[] args) throws Exception {
//通常的过滤流的定义方式
//以缓存的方式 将不同的数据写到一个文件中
DataOutputStream dos=new DataOutputStream(new BufferedOutputStream(new FileOutputStream("F:\\filetest.txt")));
byte b=3;
int i=12;
char c='a';
float f=3.3f;
//每种数据类型都有对应着的不同写入模式
dos.writeByte(b);
dos.writeInt(12);
dos.writeChar(c);
dos.writeFloat(f);
dos.close();
//此时 filetest.txt中的内容肯定是乱码 因为每中类型的byte数目是不一样的
DataInputStream dis=new DataInputStream(new BufferedInputStream(new FileInputStream("F:\\filetest.txt")));
//注意读出来的顺序应该与读进去的书序一样 这样才能保证正确恢复
System.out.println(dis.readByte()+" "+dis.readInt()+" "+dis.readChar()+" "+dis.readFloat());
}
} 输出结果:
3 12 a 3.3

结果显示与输入的是一致的,要是不想这么麻烦,就将输入信息全转化为字符串,之后再输出。

Java IO(2)的更多相关文章

  1. java.IO输入输出流:过滤流:buffer流和data流

    java.io使用了适配器模式装饰模式等设计模式来解决字符流的套接和输入输出问题. 字节流只能一次处理一个字节,为了更方便的操作数据,便加入了套接流. 问题引入:缓冲流为什么比普通的文件字节流效率高? ...

  2. Java:IO流与文件基础

    Java:IO流与文件基础 说明: 本章内容将会持续更新,大家可以关注一下并给我提供建议,谢谢啦. 走进流 什么是流 流:从源到目的地的字节的有序序列. 在Java中,可以从其中读取一个字节序列的对象 ...

  3. Java IO之字符流和文件

    前面的博文介绍了字节流,那字符流又是什么流?从字面意思上看,字节流是面向字节的流,字符流是针对unicode编码的字符流,字符的单位一般比字节大,字节可以处理任何数据类型,通常在处理文本文件内容时,字 ...

  4. java Io流向指定文件输入内容

    package com.hp.io; import java.io.*; public class BufferedWriterTest{ public static void main(String ...

  5. java Io文件输入输出流 复制文件

    package com.hp.io; import java.io.FileInputStream; import java.io.FileNotFoundException; import java ...

  6. java Io流更新文件内容

    package com.hp.io; import java.io.FileOutputStream; import java.io.IOException; public class FileOut ...

  7. java IO流详解

    流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  8. java.io.NotSerializableException: test.io.file.Student

    java.io.NotSerializableException: test.io.file.Student    at java.io.ObjectOutputStream.writeObject0 ...

  9. java.io.IOException: mark/reset not supported

    java.io.IOException: mark/reset not supported at java.io.InputStream.reset(InputStream.java:348) at ...

  10. Java IO流学习总结

    Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

随机推荐

  1. 2019 Multi-University Training Contest 3 - 1006 - Fansblog - 打表 - 暴力

    http://acm.hdu.edu.cn/showproblem.php?pid=6608 题意:给一个比较大的质数P(1e14以内),求比它小的最大的质数Q(貌似保证存在的样子,反正我没判不存在) ...

  2. python学习第四十八天json模块与pickle模块差异

    在开发过程中,字符串和python数据类型进行转换,下面比较python学习第四十八天json模块与pickle模块差异. json 的优点和缺点 优点  跨语言,体积小 缺点 只能支持 int st ...

  3. js去掉输入框的前后空格及一些常用正则表达式

    去掉TextBox输入框两头的前后空格:onblur="this.value=this.value.replace(/^\s+|\s+$/g,'');" str为要去除空格的字符串 ...

  4. python学习笔记(13):python并发编程以及系统常用模块

    一.进程与线程 1.进程:程序的一次执行(程序装载入内存,系统分配资源运行).n 每个进程有自己的内存空间.数据栈等,只能使用进程间通讯,而不能直接共享信息 2.线程:所有线程运行在同一个进程中,共享 ...

  5. vue 中使用class(样式)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. vs code 同步

    vs code 同步需要在github上配置好gist id, 将gist id添加至setting.json中, 然后再在localsetting中设置access token,  gist id ...

  7. Sublime-emmet插件的使用

    emmet是使用Sublime编写html代码时最好用的一个插件,下面简单介绍一下emmet插件的安装和使用 安装 第一步:打开sublime,首先输入command + shift + p,然后输入 ...

  8. Nginx优化总结

    目录 Nginx性能优化概述 一. 压力测试工具实战 二.了解影响性能指标 三.系统性能优化 四.静态资源优化 Nginx性能优化概述 基于Nginx性能优化,那么在性能优化这一章,我们将分为如下几个 ...

  9. Spring_搭建过程中遇到的问题

    先看一下问题: 1.在web.xml中配置Spring 加载Spring mvc的时候配置如下: <!--配置SpringMVC的前端控制器--> <servlet> < ...

  10. sys模块 json pickle模块

    # sys模块# import sys# sys.path# sys.argv# sys.exit() # 脚本退出# print('[%s]'%('#'*1))# print('[%s]'%('#' ...