Java中操作基本数据类型的流、内存操作流、打印流、随机访问流、合并流、序列化流

操作基本数据类型的流

  • 操作基本数据类型
    • DataInputStream
    • DataOutputStream

操作基本数据类型的流可以读写基本数据类型的数据,我们来写一个简单的读写例子

public class DataStreamDemo {
 public static void main(String[] args) throws IOException { 
// 写 
write(); 
// 读 
read();
 }
 private static void read() throws IOException { 
// DataInputStream(InputStream in) 
// 创建数据输入流对象 
DataInputStream dis = new DataInputStream(new FileInputStream("dos.txt")); 
// 读数据 
byte b = dis.readByte();
 short s = dis.readShort(); 
int i = dis.readInt();
 long l = dis.readLong();
 float f = dis.readFloat(); 
double d = dis.readDouble(); 
char c = dis.readChar();
 boolean bb = dis.readBoolean(); // 释放资源
 dis.close();
 System.out.println(b);
 System.out.println(s);
 System.out.println(i);
 System.out.println(l);
 System.out.println(f);
 System.out.println(d);
 System.out.println(c);
 System.out.println(bb);
 } 
private static void write() throws IOException { 
// DataOutputStream(OutputStream out)
 // 创建数据输出流对象 
DataOutputStream dos = new DataOutputStream(new FileOutputStream("dos.txt")); // 写数据 
dos.writeByte(10);
 dos.writeShort(100);
 dos.writeInt(1000);
 dos.writeLong(10000); 
dos.writeFloat(12.34F);
 dos.writeDouble(12.56);
 dos.writeChar('a');
 dos.writeBoolean(true);
 // 释放资源 
dos.close();
 }
}

内存操作流

- 操作字节数组
   - ByteArrayInputStream
   - ByteArrayOutputStream
- 操作字符数组
   - CharArrayReader
   - CharArrayWrite
- 操作字符串
   - StringReader
   - StringWriter 

内存操作流一般用于处理临时信息,因为临时信息不需要保存,使用后就可以删除。

public class ByteArrayStreamDemo { 
public static void main(String[] args) throws IOException {
 // 写数据 --字节数组输出流
 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 // 写数据 
for (int x = 0; x < 10; x++) { 
baos.write(("hello" + x).getBytes());
 } 
// 释放资源
 // 通过查看源码我们知道这里什么都没做,所以根本需要close()
 // baos.close(); 
// public byte[] toByteArray() 
byte[] bys = baos.toByteArray();
 // 读数据
 // ByteArrayInputStream(byte[] buf)
 ByteArrayInputStream bais = new ByteArrayInputStream(bys);
 int by = 0;
 while ((by = bais.read()) != -1) { 
System.out.print((char) by);
 }
 // bais.close();
 }
}

上面我们写英文字符数据可以运用字节数组的输出流ByteArrayOutputStream,如果我们写入中文数据的话就要用操作字符数组的流CharArrayWrite了。那么,剩下的操作字符数组和操作字符串的例子就不做演示了,大家可以自己练练。

打印流

  • 打印流分为两类
    • 字节流打印流 PrintStream
    • 字符打印流 PrintWriter

打印流的特点:
- 只有写数据的,没有读取数据。只能操作目的地,不能操作数据源。
- 可以操作任意类型的数据。
- 如果启动了自动刷新,能够自动刷新。
- 该流是可以直接操作文本文件的。

我们来回忆一下哪些流对象是可以直接操作文本文件的呢?

  • FileInputStream
  • FileOutputStream
  • FileReader
  • FileWriter
  • PrintStream
  • PrintWriter
  • 看API,查流对象的构造方法,如果同时有File类型和String类型的参数,一般来说就是可以直接操作文件的。

打印流的特点有一条是可以操作任意类型的数据,可是我们看方法,他的write方法不可以写boolean类型的,所以我们就去看看他的api,看有什么新方法,当然是有的,我们就直接来学习他的新方法吧。
可以操作任意类型的数据。有两种方法,他们就什么区别呢?

  • print() 不会换行,不会自动刷新数据。
  • println() 不仅仅自动刷新了数据,还实现了数据的换行。

随机访问流

RandomAccessFile
概述:RandomAccessFile类不属于流,是Object类的子类。但它融合了InputStream和OutputStream的功能。支持对随机访问文件的读取和写入。

这个类我以前写视频断点上传的时候就用到了,很强大的一个类,我们下面来学习下。

public RandomAccessFile(String name,String mode):第一个参数是文件路径,第二个参数是操作文件的模式。模式有四种,我们最常用的一种叫”rw”,这种方式表示我既可以写数据,也可以读取数据下面我们就用这个类来写一个简单的读写操作的例子

public class RandomAccessFileDemo { 
public static void main(String[] args) throws IOException { 
// 创建随机访问流对象 
RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");
 // 写入数据 
raf.writeInt(100);
 raf.writeChar('a'); 
raf.writeUTF("中国"); 
raf.close();
 }
}

运行程序,然后我们继续来写读的方法

public class RandomAccessFileDemo { 
public static void main(String[] args) throws IOException { 
// 创建随机访问流对象
 RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");
 int i = raf.readInt(); 
System.out.println(i);
 // 该文件指针可以通过 getFilePointer方法读取,并通过 seek 方法设置。 System.out.println("当前文件的指针位置是:" + raf.getFilePointer()); 
char ch = raf.readChar(); 
System.out.println(ch);
 System.out.println("当前文件的指针位置是:" + raf.getFilePointer()); String s = raf.readUTF();
 System.out.println(s);
 System.out.println("当前文件的指针位置是:" + raf.getFilePointer());
 // 我就要读取a,怎么办呢?
 raf.seek(4);
 ch = raf.readChar(); 
 System.out.println(ch); 
}
}

合并流

SequenceInputStream
概述:SequenceInputStream类可以将多个输入流串流在一起,合并为一个输入流,因此,该流也被称为合并流。

  • SequenceInputStream的构造方法
    • SequenceInputStream(InputStream s1, InputStream s2)
    • SequenceInputStream(Enumeration < ? extends InputStream> e)
    • 把多个文件的内容写入到一个文本文件

以前我们只是将一个文件的内容复制到另外一个文件中,现在这个合并流可以实现将两个及多个文件的内容复制到一个文件中了,我们来实现以下吧

// 需求:把ByteArrayStreamDemo.java和DataStreamDemo.java的内容复制到Copy.java中
public class SequenceInputStreamDemo { 
public static void main(String[] args) throws IOException { 
InputStream s1 = new FileInputStream("ByteArrayStreamDemo.java"); InputStream s2 = new FileInputStream("DataStreamDemo.java"); SequenceInputStream sis = new SequenceInputStream(s1, s2); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("Copy.java"));
 // 读写操作 
byte[] bys = new byte[1024];
 int len = 0;
 while ((len = sis.read(bys)) != -1) { 
bos.write(bys, 0, len);
 } 
bos.close();
 sis.close();
 }
}

运行程序你会在Copy.java文件中看到ByteArrayStreamDemo.java和DataStreamDemo.java文件的内容都复制到了Copy.java文件中。

那么怎么合并3个或者三个以上的文件操作呢?
// 需求:把下面的三个文件的内容(ByteArrayStreamDemo.java,CopyFileDemo.java,DataStreamDemo.java)复制到Copy.java中
public class SequenceInputStreamDemo2 { 
public static void main(String[] args) throws IOException {
 // SequenceInputStream(Enumeration e)
 // 通过简单的回顾我们知道了Enumeration是Vector中的一个方法的返回值类型。
 // Enumeration<E> elements()
 Vector<InputStream> v = new Vector<InputStream>(); 
InputStream s1 = new FileInputStream("ByteArrayStreamDemo.java"); InputStream s2 = new FileInputStream("CopyFileDemo.java"); InputStream s3 = new FileInputStream("DataStreamDemo.java"); v.add(s1);
v.add(s2);
v.add(s3);
Enumeration<InputStream> en = v.elements(); 
SequenceInputStream sis = new SequenceInputStream(en); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("Copy.java"));
 // 如何写读写呢,其实很简单,你就按照以前怎么读写,现在还是怎么读写 byte[] bys = new byte[1024]; 
int len = 0; 
while ((len = sis.read(bys)) != -1) { 
bos.write(bys, 0, len);
 } 
bos.close(); 
sis.close();
 }
}

运行程序,我们会在Copy.java文件中看到那三个文件的内容,我们要是想合并四个或者以上的文件,只需要继续将文件创建输入流对象然后添加在Vector集合中就可以实现了。

序列化流

  • 序列化流ObjectOutputStream
  • 反序列化流ObjectInputStream

序列化流:把对象按照流一样的方式存入文本文件或者在网络中传输。对象 –> 流数据(ObjectOutputStream)
反序列化流:把文本文件中的流对象数据或者网络中的流对象数据还原成对象。流数据 –>对象(ObjectInputStream)

//我们先写一个实体类,并实现序列化接口
public class Person implements Serializable { 
private String name;
 private int age;
 public Person() { 
super();
 } 
public Person(String name, int age) { 
super();
 this.name = name; 
this.age = age;
 } 
public String getName() { 
return name;
 } 
public void setName(String name) { 
this.name = name;
 } 
public int getAge() { 
return age;
 } 
public void setAge(int age) { 
this.age = age;
 } 
@Override
 public String toString() { 
return "Person [name=" + name + ", age=" + age + "]"; 
}
}
//写入数据
public class ObjectStreamDemo { 
public static void main(String[] args) throws IOException{
 // 创建序列化流对象 
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt"));
 // 创建对象
 Person p = new Person("阿杜", 25);
 // public final void writeObject(Object obj) 
oos.writeObject(p);
 // 释放资源
 oos.close();
 }
}
//读取数据
public class ObjectStreamDemo { 
public static void main(String[] args) throws IOException, ClassNotFoundException{ 
// 创建反序列化对象 
ObjectInputStream ois = new ObjectInputStream(new FileInputStream( "oos.txt")); 
// 还原对象
 Object obj = ois.readObject();
 // 释放资源 
ois.close();
 // 输出对象 
System.out.println(obj);
 }
}


输出结果:Person [name=阿杜, age=25]
我们也可以这样理解
对象序列化是将对象状态转换为可保持或传输的过程。一般的格式是与平台无关的二进制流,可以将这种二进制流持久保存在磁盘上,也可以通过网络将这种二进制流传输到另一个网络结点。对象反序列化,是指把这种二进制流数据还原成对象。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容