Java IO(2)
关于流的概念
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)的更多相关文章
- java.IO输入输出流:过滤流:buffer流和data流
java.io使用了适配器模式装饰模式等设计模式来解决字符流的套接和输入输出问题. 字节流只能一次处理一个字节,为了更方便的操作数据,便加入了套接流. 问题引入:缓冲流为什么比普通的文件字节流效率高? ...
- Java:IO流与文件基础
Java:IO流与文件基础 说明: 本章内容将会持续更新,大家可以关注一下并给我提供建议,谢谢啦. 走进流 什么是流 流:从源到目的地的字节的有序序列. 在Java中,可以从其中读取一个字节序列的对象 ...
- Java IO之字符流和文件
前面的博文介绍了字节流,那字符流又是什么流?从字面意思上看,字节流是面向字节的流,字符流是针对unicode编码的字符流,字符的单位一般比字节大,字节可以处理任何数据类型,通常在处理文本文件内容时,字 ...
- java Io流向指定文件输入内容
package com.hp.io; import java.io.*; public class BufferedWriterTest{ public static void main(String ...
- java Io文件输入输出流 复制文件
package com.hp.io; import java.io.FileInputStream; import java.io.FileNotFoundException; import java ...
- java Io流更新文件内容
package com.hp.io; import java.io.FileOutputStream; import java.io.IOException; public class FileOut ...
- java IO流详解
流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
- java.io.NotSerializableException: test.io.file.Student
java.io.NotSerializableException: test.io.file.Student at java.io.ObjectOutputStream.writeObject0 ...
- java.io.IOException: mark/reset not supported
java.io.IOException: mark/reset not supported at java.io.InputStream.reset(InputStream.java:348) at ...
- Java IO流学习总结
Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
随机推荐
- Appium+Python之生成html测试报告
思考:测试用例执行后,如何生成一个直观漂亮的测试报告呢? 分析:1.unittest单元测试框架本身带有一个textTestRunner类,可以生成txt文本格式的测试报告,但是页面不够直观 2.我们 ...
- 如何在nuxt中添加proxyTable代理
背景 在本地开发vue项目的时候,当你习惯了proxyTable解决本地跨域的问题,切换到nuxt的时候,你会发现,添加了proxyTable设置并没有什么作用,那是因为你是用的vue脚手架生成的vu ...
- Python2中range 和xrange的区别??
两者用法相同,不同的是range返回的结果是一个列表,而xrange的结果是一个生成器, 前者是直接开辟一块内存空间来保存列表,后者是边循环边使用,只有使用时才会开辟内存空间, 所以当列表很长时,使用 ...
- C# ASP.NET 手写板并生成图片保存
前端: @{ Layout = null; } <!DOCTYPE html> <html lang="zh-CN"> <head> <t ...
- C# asp.net XML格式的字符串显示不全
前台显示XML字符串显示不全 后台XML字符串使用<xmp></xmp>将XML格式字符串括起来
- vue修改Element的el-table样式
修改Element中的el-table样式,可以使用以下几种方法: 1. row-style 行的 style 的回调方法,也可以使用一个固定的 Object 为所有行设置一样的 Style. 2. ...
- Linux架构之Nginx Web基础1
第41章 Nginx Web基础入门 41.1 Nginx部署 41.1.1 Nginx的安装方式 源码编译 官方仓库 epel仓库 优点 规范 安装简单 安装简单 便于管理 配置易读 缺 ...
- Matlab的2D作图
1 plot()函数 画一条线 plot(X,Y) 最基本的例子 x = 0: pi / 100:2 * pi; y = sin(x); figure plot(x,y) 在一张图上画多条线 clc; ...
- 三、ARM 寄存器及异常处理
3.1 ARM 内部寄存器 ARM920T 总共有 37 个寄存器,其中 31 通用 32 位寄存器和 6 个状态寄存器,但不能在同一时刻对所有的寄存器可见.处理器状态和运行模式决定了哪些寄存器对程序 ...
- stream benchmark 介绍
英文原版 https://www.cs.virginia.edu/stream/ref.html FAQ中有关于STREAM_ARRAY_SIZE NTIME OFFSET STREAM_TYPE的设 ...