一、PrintStream和PrintWriter

PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。

PrintStream 打印的所有字符都使用平台的默认字符编码转换为字节。

在需要写入字符而不是写入字节的情况下,应该使用 PrintWriter 类。

 /**
* PrintStream
* 1.提供了打印方法,可以对多种类型值进行打印,并保持数据的原有格式
* 2.它不抛IOException
*
* 构造函数 接受三种类型的值
* 1.字符串路径
* 2.File对象
* 2.字符输出流
*/
public class PrintStreamDemo { public static void main(String[] args) throws IOException {
PrintStream out=new PrintStream("print.txt");
out.write(97);//a 特点:只保留数最低的八位
out.write(610);//a
out.print(97);//97 特点:将数据先转成String类型,再打印出来
}
}
 /**
* PrintWriter:字符打印流
* 构造方法参数:
* 1.字符串路径
* 2.File对象
* 3.字节输出流
* 4.字符输出流
*/
public class PrintWriterDemo { public static void main(String[] args) throws IOException {
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));//读取流
//字符写入流
PrintWriter pw=new PrintWriter(new FileWriter("out.txt"),true);//自动刷新
String line=null;
while((line=bufr.readLine())!=null){
if(line.equals("over")){
break;
}
pw.println(line.toUpperCase());
}
pw.close();
bufr.close();
}
}

二、ObjectOutputStream和ObjectInputStream以及Serializable接口

ObjectOutputStream为了延长对象的生命周期,把对象序列化存储到硬盘的文件中,写入的对象必须实现Serializable接口;

ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化

writeObject 方法用于将对象写入流中。所有对象(包括 String 和数组)都可以通过 writeObject 写入。

可将多个对象或基元写入流中。必须使用与写入对象时相同的类型和顺序从相应 ObjectInputstream 中读回对象。

readObject 方法用于从流读取对象。应该使用 Java 的安全强制转换来获取所需的类型。

在 Java 中,字符串和数组都是对象,所以在序列化期间将其视为对象。读取时,需要将其强制转换为期望的类型

 public class ObjectStreamDemo {

     public static void main(String[] args) throws IOException, ClassNotFoundException {
writeObjectDemo();
readObjectDemo();
} public static void readObjectDemo() throws IOException, ClassNotFoundException {
//ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("out.object"));
Person p=(Person)ois.readObject();
Person p2=(Person)ois.readObject();
System.out.println(p.getName()+"::"+p.getAge());//花蝴蝶::12
System.out.println(p2.getName()+"::"+p2.getAge());//大脸猫::2
} public static void writeObjectDemo() throws IOException, FileNotFoundException {
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("out.object"));
oos.writeObject(new Person("花蝴蝶",12));
oos.writeObject(new Person("大脸猫",2));
oos.close();
}
}

* Serializable接口可以为被序列化的类提供类ID号

* 来判断存储的对象和类是否是同一个版本

* 如果ID号不同的话,会发生InvaildClassException异常

*

* transient:如果一个属性不是静态化的,但又不想被序列化存储,就可以用这个关键字修饰

下面是实现了Serializable接口的Person类的代码:

 package www.brighten.io;

 import java.io.Serializable;

 public class Person implements Serializable {
/**
* Serializable接口可以为被序列化的类提供类ID号
* 来判断存储的对象和类是否是同一个版本
* 如果ID号不同的话,会发生InvaildClassException异常
*
* transient:如果一个属性不是静态化的,但又不想被序列化存储,就可以用这个关键字修饰
*/
private static final long serialVersionUID = 3221L;
private transient String name;
private static int age;
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;
} }

三、RandomAccessFile

此类的实例支持对随机访问文件的读取和写入。

随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。

存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。

* RandomAccessFile这个类从名字就可以看出,

* 不是IO体系总的子类,它的父类是Object

* 特点:

* 1.既能读,又能写。

* 2.该对象内部维护了一个大型byte数组,可以通过指针对数组元素进行操作

* 3.可以通过getFilePointer获取指针;通过seek方法设置指针位置

* 4.其实该对象就是对字节输入流和输出流进行了封装

* 5.该对象的源或者目的只能是文件,通过构造方法可以看出。

 package www.brighten.io;

 import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile; public class RandomAccessFileDemo { public static void main(String[] args) throws IOException {
writeFiles();
randomWrite();
readFiles();
}
public static void randomWrite() throws IOException {
RandomAccessFile raf=new RandomAccessFile("randomFile.txt", "rw");
raf.seek(3*8);
/**
* 可以让不同的线程对不同的部分进行写入
* 应用如断点续传
*/
raf.write("爱新觉罗溥仪".getBytes());
raf.writeInt(22);
raf.close(); }
public static void readFiles() throws IOException {
RandomAccessFile raf=new RandomAccessFile("randomFile.txt", "rw");
//用seek方法设置指针的位置,直接读取第二个人的信息
raf.seek(8);
byte[] buf=new byte[4];
raf.read(buf);
String name=new String(buf); int age=raf.readInt();
System.out.println("name="+name);//name=杜甫
System.out.println("age="+age);//age=99 raf.close();
}
//使用RandomAccessFile写入一些人员信息,比如,姓名和年龄
public static void writeFiles() throws IOException {
/**
* IO流不同,存不存在,都会创建
* RandomAccessFile,如果文件不存在,则创建;如果文件存在,就不创建
*/
RandomAccessFile raf=new RandomAccessFile(new File("randomFile.txt"), "rw");
raf.write("李白".getBytes() );
raf.writeInt(97);
raf.write("杜甫".getBytes() );
raf.writeInt(99);
raf.close();
}
}

四、PipedInputStream和PipedOutputStream

管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。

通常,数据由某个线程从 PipedInputStream 对象读取,并由其他线程将其写入到相应的 PipedOutputStream

不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。

 public class PipedStream {

     public static void main(String[] args) throws IOException {
PipedInputStream in=new PipedInputStream();
PipedOutputStream out=new PipedOutputStream();
in.connect(out);//管道读取流和写入流相连接
new Thread(new Input(in)).start();
new Thread(new Output(out)).start();
}
}
class Input implements Runnable{
private PipedInputStream in;
public Input(PipedInputStream in){
this.in=in;
}
@Override
public void run() {
byte[] buf=new byte[1024];
int len;
try {
len = in.read(buf);
String str=new String(buf,0,len);
System.out.println(str);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} class Output implements Runnable{
private PipedOutputStream out;
public Output(PipedOutputStream out){
this.out=out;
}
@Override
public void run() {
try {
Thread.sleep(3000);
out.write("Hello,管道流来了!".getBytes());
} catch (Exception e) {
e.printStackTrace();
}
}
}

五、DataInputStream和DataOutputStream

数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。

数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入。

 public class DataStreamDemo {

     public static void main(String[] args) throws IOException {
writeDemo();
readDemo();
} public static void readDemo() throws IOException {
DataInputStream dis=new DataInputStream(new FileInputStream("data.txt"));
String str=dis.readUTF();
dis.close();
System.out.println(str);
} public static void writeDemo() throws IOException {
DataOutputStream dos=new DataOutputStream(new FileOutputStream("data.txt"));
dos.writeUTF("世界,你好!");
dos.close();
}
}

六、以ByteArrayInputStream为代表的类

ByteArrayInputStream 包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪 read 方法要提供的下一个字节。

关闭 ByteArrayInputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException

特点:源和目的都是内存

类似的类有CharArrayReader 、CharArrayWriter、StringReader、 StringWriter。

 public class ByteArrayStreamDemo {
public static void main(String[] args) {
ByteArrayInputStream bais=new ByteArrayInputStream("Hello World!".getBytes());
ByteArrayOutputStream baos=new ByteArrayOutputStream();
int ch=0;
while((ch=bais.read())!=-1){
baos.write(ch);
}
System.out.println(baos.toString());//Hello World!
}
}

七、编码问题(解码错误的补救方法和联通问题)

开发常用的编码有GBK、utf-8

* 字符串-->字节数组:编码

* 字节数组-->字符串:解码

* 你好的GBK编码:-60  -29  -70  -61

* 你好的UTF-8编码:-28  -67  -96  -27  -91  -67

 public class EncodeDemo {

     public static void main(String[] args) throws UnsupportedEncodingException {
//demo1();
demo2();
} /**
* 如果你编错了,肯定解不出来
如果解错了,可能还有办法补救
*/
public static void demo1() throws UnsupportedEncodingException {
String str=new String("自律给我自由");
//编码
byte[] buf=str.getBytes("GBK");
//printBytes(buf);
//解码
String s1=new String(buf,"iso8859-1");
System.out.println("s1="+s1);//s1=×???????×??? //解码错误,补救方法
byte[] buf2=s1.getBytes("iso8859-1");//获取源字节
String s2=new String(buf2,"GBK");
System.out.println("s2="+s2);//s2=自律给我自由
}
/**
* 补救失败,因为按照GBK编码得到的字节在utf-8中无法查到对应数据,就用了别的字符替代
* 这样再次解码成字节后,已经不是原来的字节数组了
* 特例:“谢谢”可以。
* 所以说“解码错了,可能还有方法补救”
* @throws UnsupportedEncodingException
*/
public static void demo2() throws UnsupportedEncodingException {
String str=new String("举杯邀明月");
byte[] buf=str.getBytes("gbk");
printBytes(buf);//-66 -39 -79 -83 -47 -5 -61 -9 -44 -62 String s1=new String(buf,"utf-8");
System.out.println("s1="+s1); //用demo1中的方法补救
byte[] buf2=s1.getBytes();
printBytes(buf2);//63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
String s2=new String(buf2,"gbk");
System.out.println("s2="+s2);
} public static void printBytes(byte[] buf) {
for(byte b:buf){
System.out.print(b+" ");
}
System.out.println();
}
}

* 有一个让人疑惑的现象。

* 用Windows记事本新建一个文件,在里面写上“联通”两字

* 保存以后再打开,就会看到"��ͨ",这种很奇怪的字符,

* 下面的程序就来分析一下原因。

* 运行程序后可以得到“联通”的GBK编码的字节是

11000001

10101010

11001101

10101000

开头依次是110、10、110、110;正好也符合utf-8两个字节一个字符的编码特点,

所以记事本就以utf-8的规则进行解码了,而没用GBK解码,所以出现了乱码

 public class LianTongBug {

     public static void main(String[] args) throws IOException {
String str=new String("联通");
byte[] buf=str.getBytes("gbk");
for(byte b:buf){
System.out.println(Integer.toBinaryString(b&255));//只取后八位
}
}
}

IO包中的其他类总结的更多相关文章

  1. 黑马程序员——【Java基础】——File类、Properties集合、IO包中的其他类

    ---------- android培训.java培训.期待与您交流! ---------- 一.File类 (一)概述 1.File类:文件和目录路径名的抽象表现形式 2.作用: (1)用来将文件或 ...

  2. Java基础---IO(三)--IO包中的其他类

    第一讲     对象序列化 一.概述 将堆内存中的对象存入硬盘,保留对象中的数据,称之为对象的持久化(或序列化).使用到的两个类:ObjectInputStream和ObjectOutputStrea ...

  3. IO包中的RandomAccessFile类

    RandomAccessFile RandomAccessFile 是随机访问文件的类.它支持对文件随机访问的读取和写入,即我们也可以从指定的位置读取/写入文件数据,因为该类在其内部封装了一个数组和指 ...

  4. IO包中的其他类

    查看各对象API文档 打印流 PrintWriter PrintStream 序列流:对多个流进行排列合并 SequenceInputStream public static void main(St ...

  5. Java笔记(二十八)……IO流下 IO包中其他常用类以及编码表问题

    PrintWriter打印流 Writer的子类,既可以接收字符流,也可以接收字节流,还可以接收文件名或者文件对象,非常方便 同时,还可以设置自动刷新以及保持原有格式写入各种文本类型的print方法 ...

  6. IO 包中的其他类

    打印流 PrintWriter 和 PrintWriter 直接操作输入流和文件 序列流 SequenceInputStream 对多个输入流进行合并 操作对象 ObjectInputStream 和 ...

  7. Java之IO(十四)IO包中其它类

    转载请注明出处:http://www.cnblogs.com/lighten/p/7267553.html 1.前言 此章介绍IO包中剩余未介绍的几个流和工具类,包括LineNumberReader. ...

  8. java.io包中的字节流—— FilterInputStream和FilterOutputStream

    接着上篇文章,本篇继续说java.io包中的字节流.按照前篇文章所说,java.io包中的字节流中的类关系有用到GoF<设计模式>中的装饰者模式,而这正体现在FilterInputStre ...

  9. Java IO流中的File类学习总结

    一.File类概述 File类位于java.io包中,是对文件系统中文件以及文件夹进行封装的对象,可以通过对象的思想来操作文件和文件夹. File类有多种重载的构造方法.File类保存文件或目录的各种 ...

随机推荐

  1. cas php

    CAS的php客户端实践—单点登录整合php程序 兄弟近日尝试将一个php程序以单点登录方式和原有的系统整合在一起.验证服务器选用的是CAS,其提供有相应的php客户端.整个过程如下:1.搭建CAS服 ...

  2. CNN学习笔记:批标准化

    CNN学习笔记:批标准化 Batch Normalization Batch Normalization, 批标准化, 是将分散的数据统一的一种做法, 也是优化神经网络的一种方法. 在神经网络的训练过 ...

  3. OAuth 白话简明教程 5.其他模式

    转自:http://www.cftea.com/c/2016/11/6706.asp OAuth 白话简明教程 1.简述 OAuth 白话简明教程 2.授权码模式(Authorization Code ...

  4. SVD在餐馆菜肴推荐系统中的应用

    SVD在餐馆菜肴推荐系统中的应用 摘要:餐馆可以分为很多类别,比如中式.美式.日式等等.但是这些类别不一定够用,有的人喜欢混合类别.对用户对菜肴的点评数据进行分析,可以提取出区分菜品的真正因素,利用这 ...

  5. Common Knowledge

    2014-08-23 11:01:11 -6:四面体 (1)内切球半径:r = 3V / (S1+S2+S3+S4) (2)体积:将四点组成三个向量AB,AC,AD,向量的混合积就是它们组成的平行六面 ...

  6. asp.net 获取mp3 播放时长

    1 Shell32 //添加引用:COM组件的Microsoft Shell Controls And Automation //然后引用 using Shell32; //如果出现“无法嵌入互操作类 ...

  7. pyDay16

    内容来自廖雪峰的官方网站. 1.Python内建的filter()函数用于过滤序列. 2.和map()类似,filter()也接收一个函数和一个序列.和map()不同的是,filter()把传入的函数 ...

  8. SNMP学习笔记之SNMPWALK 命令

    SNMPWALK是一个通过SNMP GET-NEXT类型PDU,实现对目标AGENT的某指定MIB分支信息进行完整提取输出的命令工作. 命令行: snmpwalk [选项] agent [oid] 选 ...

  9. bzoj2721 / P1445 [Violet]樱花

    P1445 [Violet]樱花 显然$x,y>n$ 那么我们可以设$a=n!,y=a+t(t>0)$ 再对原式通分一下$a(a+t)+ax=x(a+t)$ $a^{2}+at+ax=ax ...

  10. JavaWeb实现分页的四种方法

    一.借助数组进行分页 原理:进行数据库查询操作时,获取到数据库中所有满足条件的记录,保存在应用的临时数组中,再通过List的subList方法,获取到满足条件的所有记录. 实现: 首先在dao层,创建 ...