关于流的概念

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. HDU 4285 circuits( 插头dp , k回路 )

    circuits Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  2. SQL SERVER SP命令及实现跨数据库查询

    1.数据库: (1)sp_helpdb:报告有关指定数据库或所有数据库的信息. 例:sp_helpdb   --显示所有数据库信息(名称.大小等) 例:sp_helpdb Recruitment   ...

  3. k3 cloud成本调整单

    做了成本调整单中的入库调整单或者出库调整单,进行入库成本核算和出库成本核算,做了入库调整单后在存货收发汇总表(按日期报表)中的收入部分会展示出来: 如果做的是期末余额成本调整,核算时会先删除手工新增的 ...

  4. Rsync+sersync 数据同步指南

    (1):sersync 可以记录下被监听目录中发生变化的(包括增加.删除.修改)具体某一个文件或 某一个目录的名字: (2):rsync 在同步的时候,只同步发生变化的这个文件或者这个目录(每次发生变 ...

  5. 如何在Linux下手动编译安装gcc

    如果可以通过apt来安装的话,尽量不要手工编译了,手工编译是最后的选择.用apt安装,只需要输入一条命令: sudo apt-get install gcc 手工编译的话,gcc和其他软件包存在如下的 ...

  6. Linux 内核层和 用户层 配置 GPIO 引脚

    Linux BSP 开发的基础就是和GPIO打交道, 下面总结下这几天对某家开发板的GPIO控制的知识. 公司的开发板用的是 DTB  模式 ,首先,进入 dts,dtsi文件查看关于GPIO 的模块 ...

  7. Firewalld--02 端口访问/转发、服务访问、源地址管理

    目录 防火墙端口访问/转发.服务访问.源地址管理 1. 防火墙端口访问策略 2. 防火墙服务访问策略 3.防火墙接口管理 4.防火墙源地址管理 5. 防火墙端口转发策略 防火墙端口访问/转发.服务访问 ...

  8. CA认证机制的简明解释

    公钥机制面临的问题: 假冒身份发布公钥! 可以用CA来认证公钥的身份.CA有点像公安局,公钥就像身份证.公安局可以向任何合法用户颁发身份证以证明其合法身份.第三方只要识别身份证的真伪就能判断身份证持有 ...

  9. 03机器学习实战之决策树scikit-learn实现

    sklearn.tree.DecisionTreeClassifier 基于 scikit-learn 的决策树分类模型 DecisionTreeClassifier 进行的分类运算 http://s ...

  10. 洛谷 P2783 有机化学之神偶尔会做作弊(Tarjan,LCA)

    题目背景 LS中学化学竞赛组教练是一个酷爱炉石的人. 有一天他一边搓炉石一边监考,而你作为一个信息竞赛的大神也来凑热闹. 然而你的化竞基友却向你求助了. “第1354题怎么做”<--手语 他问道 ...