一、字节数组流

  之前使用输入输出流的操作的对象是文件,而这里字节数组流操作的对象是内存,内存可以看做是一个字节数组。

  使用字节数组流读写就可以看做是从内存A到内存B的读写,对象时内存即字节数组。

  

  1.1构造方法

    ByteArrayOutputStream()//创建一个字符数组输出流

    ByteArrayInputStream(byte[] buf)//创建一个字节数组输入流,这里面的buff可看做内存对象即字符数组

  

  2.2主要方法

    ByteArrayInputStream:

    read(byte[] bu)//读取输入流中的数据,放入bu中。

    ByteArrayOutputStream:

    public void write(byte[] bu)//将bu(可看做内存对象数据),写入输出流。

    byte[] toByteArray()//创建一个新的字节数组,并将输出流中数据放入其中

  2.3例子

    

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream; public class ByteArrayStream { public static void main(String[] args) {
// TODO Auto-generated method stub
read(write());
}
public static void read(byte[] by){
int len = 0;
//将内存对象B放入输入流
InputStream r = new BufferedInputStream(new ByteArrayInputStream(by));//把这里的by看做内存对象
byte[] flush = new byte[1024];//把flush看做另外一个内存对象
try {
//将内存对象B与输入流关联,来后通过输入流读取对象B数据放入flush中
while(-1 != (len = r.read(flush))){//读取输入流中的数据放入flush,即读取内存对象B中的数据
System.out.println(new String(flush,0,len));//打印出读取的数据
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public static byte[] write(){
byte[] by = null;//内存对象B
byte []info = "字节数组流".getBytes();//内存对象A
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
bos.write(info);//将内存A块内容写入输出流
by = bos.toByteArray();//内存对象B接收输出流中的数据
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return by;//返回内存对象B
} }
运行结果:
字节数组流

wtire:首先将内存A的数据写入输出流,然后内存B获取输入流中的数据,最后将内存B作为返回值。

read:将内存B放入输入流,然后通过输入流读取内存B中的数据放入flush中,然后将flush转为字符打印出来。

这里在一个程序中运行看着有点奇怪而且不好理解,我们就把内存A内存B看着是两台电脑各自内存,这样便于理解一些。

二、数据流

  采用数据流进行读写可以允许将原始java数据类型写入流中,即既保持了数据也保存了数据类型。

  2.1构造方法

    DataInputStream(InputStream  in)

    DataOutputStream(OutStream out)

  2.2主要方法

    void writeInt(int v)//写入int型数据

    void writeLong(long v)//写入long型数据

    void writeUTF(String str)//将字符串以UTF-8格式写入输出流

    

    int readInt()//读取Int型数据并返回

    long readLong()//读取long型数据并返回

    String readUTF()//读取UTF-8转换的字符串

    基本操作方法与文件读写无太大差别,只是加上了数据类型,这些方法时DataStream独有的方法,故调用它们要避免多态。

  2.3例子

    

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException; public class DateStream { public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
write();
read();
}
public static void read() throws IOException{
DataInputStream dis = new DataInputStream(//数据流
new BufferedInputStream(//缓冲流
new FileInputStream(
new File("F:\\依风\\Desktop\\data.txt")
)
)
);
//注意:这里读取类型的顺序要和写入时的类型顺序对应,不然会出现错误。
long lo = dis.readLong();//将不同类型用对应方法读出。
int in = dis.readInt();
String str = dis.readUTF();
dis.close();
System.out.println(lo + "-->" + in +"-->" + str);
} public static void write() throws IOException{
long lo = 100L;
int in = 21;
String str = "DataStream";
DataOutputStream dos = new DataOutputStream(//数据流
new BufferedOutputStream(//缓冲流
new FileOutputStream(
new File("F:\\依风\\Desktop\\data.txt")
)
)
);
dos.writeLong(lo);//将不同类型用对应的方法写入
dos.writeInt(in);
dos.writeUTF(str);
dos.flush();
dos.close();
}
}
运行结果:
100-->21-->DataStream

这里一开始往文件中写入的是long型,然后是int类型最后是String

那么读取时也应该先读long,然后int最后String。

如果写入和读取的顺序不一致可能会导致读取的数据有误,也可以出现EOFException。

这里写入的数据不是给人类看的,而是给机器识别的。我可以打开写入的文件会发现里面会有乱码。

三、对象流

    使用对象流,可以写入、读出对象的信息以及属性属性。对象流和之前输入输出流功能类似,

    不过是将之前的文件换成了对象,这里的对象时我们通过new创建的对象。

    将对象写如文件实质是是将对象转换为字节序列,然后将字节序列写入文件,这个称为序列化。

    读取字节序列然后转换为对象就称为反序列化。

    对象被序列化必须实现java.io.Serializable接口,改接口表示可以序列化。对象的类没有实现这个接口会出现一次次。

    对象中某些属性不想被序列化可以加transient修饰,transient修饰就代表这个属性不参加序列化。

    3.1构造方法

    Public ObjectOutputStream(OutputStream out)

    Public ObjectInputStream(InputStream in)

    

    3.2主要方法

    Object readObject()//从输入流中读取对象

     void writeObject(Object obj)//将obj写入输出流

    3.3例子 

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; public class ObjectStream {
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException{
read(write());
}
//将对象写入指定文件,并返回指定文件路径信息
public static String write() throws FileNotFoundException, IOException{
String filePath = "F:\\依风\\Desktop\\ObjectStream.txt";
ObjectOutputStream oos = new ObjectOutputStream(//使用独有方法,不发生多态
new BufferedOutputStream(
new FileOutputStream(
new File(filePath))));
oos.writeObject(new Employ("hcf",4000));//传入对象
oos.flush();
oos.close();
return filePath;
} //接受指定文件路径信息,并读取文件中的对象
public static void read(String filePath) throws FileNotFoundException, IOException, ClassNotFoundException{
ObjectInputStream ois = new ObjectInputStream(
new BufferedInputStream(
new FileInputStream(
new File(filePath))));
Employ em = (Employ)ois.readObject();//将读取的对象强制转型
System.out.println(em.getName() + ":" + em.getMoney());//输出对象信息
}
} class Employ implements java.io.Serializable{//必须实现接口
private transient String name;//姓名没有被序列化
private int money;
public Employ(){}
public Employ(String name,int money){
setName(name);
setMoney(money);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
运行结果:
null:4000

我们可以看到没有被序列化的属性显示为null

比如一个矩形类中有长、宽属性,还有面积属性,

那么序列化时可以不序列化面积属性,因为面积属性可以通过长宽计算出来。  

四、打印流

    打印流(PraintStream)类似输出流,但打印流使用方便而且可以打印出任何类型的数据。

    想我们平常使用很多的System.out.println()就是调用打印流中的println()方法。

    4.1构造函数

    PrintStream(OutputStream out)//创建打印流

    PrintStream(OutputStream out, boolean autoFlush)//创建打印流,autoFlush为true代表自动刷新缓冲区
    PrintStream(File fileName, String csn)//创建指定文件的打印流,csn为编码方式

    4.3主要方法

    print(......);//打印参数内容,几乎可为任何形式参数,末尾不加回车。

    println(......)//打印参数内容,末尾加回车。

    

    

    4.4例子 

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.Scanner; public class Print {
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException{
PrintStream ps = new PrintStream(//常规初始化
new BufferedOutputStream(
new FileOutputStream(
new File("F:\\依风\\Desktop\\print.txt"))));
PrintStream pc = new PrintStream("F:\\依风\\Desktop\\printCsn.txt","GBK");//指定编码
PrintStream pf = new PrintStream(//自动刷新
new BufferedOutputStream(
new FileOutputStream(
new File("F:\\依风\\Desktop\\printFlush.txt"))),true);
pf.println("autoFlush");
pf.close();
pc.print("GBK");
pc.flush();
pc.close();
ps.print("print\n"+1.3);
ps.flush();
ps.close();
}
}

运行结果:

4.5 Sytem.out和 System.in

我们平常调用System.out.println()函数打印,打印的内容是显示在控制台上的,System.out也是一个打印流。

而这个打印流关联的就是控制台,可以把控制台也看做一个文件,平常打印出来的数据就是往控制台这个文件打印。

那么我们能否将这个文件换成别的文件呢,即调用System.out.println()不是向控制台输出信息,而是向我们指定的文件输入信息。

答案是可以的,System里面提供了一个方法System.SetOut(PrintStream out)方法,可以设置System.out。

可以看到参数是一个打印流。

设置指定的参数后,Sytem.out.println()就会将内容打印到指定的打印流中。

public class Print {
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException{
System.setOut(new PrintStream(new FileOutputStream(new File("F:\\依风\\Desktop\\print.txt"))));
System.out.println("setOut");
}
}

还有System.in,这个比较常用的用法就是作为Scanner的参数,表示从键盘输入。

System.in其实就是一个输入流(InputStream),而System.in默认是键盘,这里可以把键盘也看做一个文件,就是从键盘这个文件读取内容。

那么同样的,我们也可以将System.in修改为其他文件。

就需要用到System.setIn(InputStream in).这时就是读取设置之后的输入流

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.Scanner; public class Print {
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException{
//重定向了System.in将原来的将键盘输入更改为其他输入
System.setIn(new BufferedInputStream(new FileInputStream(new File("F:\\依风\\Desktop\\print.txt"))));
Scanner si = new Scanner(System.in);
System.out.println(si.nextLine());//读取一行 }
}
运行结果:
setOut//根据文件内容决定

那么我么修改了Sytem.in(键盘输入)和System.out(控制台输出)为其他的文件后是否可以还原它们,当然是可以的,之前说了键盘、控制台都是文件

(在windows中一切都可以看做是文件),现在的关键就是要找到代表控制台可键盘的文件,然后再次Set就可以了。

我们来看下源码:

其中FileDescriptor.in就代表键盘,....out就代表控制台,

public class Print {
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException{
//输出重定向为指定文件
System.setOut(new PrintStream(new FileOutputStream(new File("F:\\依风\\Desktop\\print.txt"))));
System.out.println("setSystem.outAndSystem.in");
System.out.close();
//输出重定向为控制台
System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
//输入重定向为指定文件
System.setIn(new BufferedInputStream(new FileInputStream(new File("F:\\依风\\Desktop\\print.txt"))));
Scanner si = new Scanner(System.in);
System.out.println(si.nextLine());//内容输出控制台
}
}
运行结果:
setSystem.outAndSystem.in

还有一个System.err也是一个打印流,这个主要用于打印出错误信息。比如:

这些红色的错误信息就是err打印出来的。

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.Scanner; public class Print {
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException{
System.err.println("错误信息");
}
}

运行结果:

6.5(java学习笔记)其他流(字节数组流,数据流,对象流,打印流)的更多相关文章

  1. Java学习笔记之---方法和数组

    Java学习笔记之---方法与数组 (一)方法 (1)什么是方法? 方法是解决一类问题的步骤的有序组合 方法包含于类或对象中 方法在程序中被创建,在其他地方被引用 (2)方法的优点 使程序变得更简短而 ...

  2. java学习笔记IO之字节输入输出流

    IO字节输入输出流 OutputStream:字节输出流 该抽象类是所有字节输出流的超类: 定义了一些共性的成员方法: 1.写入一个字节 void write(int b);//b表示字节 2.写入字 ...

  3. 【Java学习笔记】集合转数组---toArray()

    package p2; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class ...

  4. java学习笔记(三):类和对象

     创建对象 构造器 每一个类都有一个构造器. 如果我们不单独为一个类编写构造器那么 Java 的编译器将会给这个类建立一个默认的构造器. 每当一个新的对象被创建,至少一个构造器将会被调用. 构造器的一 ...

  5. java学习笔记(2)——数组

    1.创建数组: int[] a = new int[n];//数组长度n不要求为常数,一旦创建了数组,其大小不可改变 int[] a = {0,1,2,3};//也可这样定义 获得数组元素的个数:ar ...

  6. Java学习笔记----你可能不知道那些知识,对象复制与引用

    1.private ,protected,static不能用来修饰interface. 2.java在处理基本数据类型(比如int ,char,double)时,都是採用按值传递的方式运行.除此之外的 ...

  7. java学习笔记之反射—Class类实例化和对象的反射实例化

    反射之中所有的核心操作都是通过Class类对象展开的,可以说Class类是反射操作的根源所在,但是这个类的实例化对象,可以采用三种方式完成. java.lang.Class类的定义: public f ...

  8. Java学习笔记(五)——数组

    一.数组使用方法 1. 声明数组 语法: 数据类型[ ] 数组名: 或者   数据类型 数组名[ ]: 其中,数组名可以是任意合法的变量名 2. 分配空间 简单地说,就是指定数组中最多可存储多少个元素 ...

  9. Java学习笔记15(面向对象八:匿名对象、内部类)

    匿名对象: 是指创建对象的时候,只有创建对象的语句,却没有把对象地址值赋给某个变量 创建一个普通对象: Person p = new Person(); 创建一个匿名对象: new Person(); ...

  10. Java学习笔记之基础语法(数组)

    数组 数组概述:是具有相同数据类型的数据的集合 数组的定义:数据类型 数组名 [] 数组特点: 1,数组是引用数据类型. 2,数组值用大括号,元素之间用逗号隔开,元素的个数是0-N个 3,数组长度是固 ...

随机推荐

  1. 单个回调函数中返回多个Request以及Item

    import scrapy from myproject.items import MyItem class MySpider(scrapy.Spider): name = 'example.com' ...

  2. linux 端口号、进程id、杀进程、查询tcp的连接(各种状态的)

    sudo netstat -antupkill -s 9 50713netstat -n | grep 61616netstat -n | awk '/^tcp/ {++S[$NF]} END {fo ...

  3. eclipse 主题文件配置

    eclipse市场搜索 Eclipse Color Theme ----用于控制文本域主题 Eclipse 4 Chrome Theme  chrome风格的主题 最新的:Jeeeyul's Them ...

  4. POJ 1320 Street Numbers 解佩尔方程

    传送门 Street Numbers Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2529   Accepted: 140 ...

  5. Bzoj1692 洛谷P2870 [Usaco2007 Dec]队列变换

    Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1570  Solved: 656 Description FJ打算带他的N(1 <= N <= ...

  6. bzoj1503: [NOI2004]郁闷的出纳员 fhqtreap版

    这道题写法和之前差不多 但是fhqtreap在加点的时候为了同时维护大根堆以及二叉排序树的性质所以插入时也要注意分裂 fhqteap需要判断指针是否为空 不然就会re 这个我调了很久 #include ...

  7. 【BZOJ】1692: [Usaco2007 Dec]队列变换

    [算法]字符串hash [题解] 显然如果字母互不相同,贪心取是正确的. 如果存在字母相同,那么就换成比较后缀和前缀嘛. 但是要注意,不是后缀和前缀相同就能直接跳跃,每次必须只推一位. 取模的哈希比自 ...

  8. 稀疏编码学习笔记(二)L2范数

    L2范数 除了L1范数,还有一种更受宠幸的规则化范数是L2范数: ||W||2.它也不逊于L1范数,它有两个美称,在回归里面,有人把有它的回归叫“岭回归”(Ridge Regression),有人也叫 ...

  9. POJ3466(01背包变形)

    Proud Merchants Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) ...

  10. mac air上archlinux的安装及优化

    前言 最近总感觉跑了两年多ubuntu系统的MacBookAir6,2越来越不行了,内存总是亮红灯,软件效率也低了不少.最直接的解决方法当然是换电脑,购买一台配置更好的,比如2017款xps,不过在我 ...