一、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. NodeJS学习笔记二

    类声明和类表达式 ES6 中的类实际上就是个函数,而且正如函数的定义方式有函数声明和函数表达式两种一样,类的定义方式也有两种,分别是:类声明.类表达式. 类声明 类声明是定义类的一种方式,就像下面这样 ...

  2. 无界面Ubuntu服务器搭建selenium+chromedriver+VNC运行环境

    搭建背景 有时候我们需要把基于selenium的爬虫放到服务器上跑的时候,就需要这样一套运行环境,其中VNC是虚拟的显示模式,用于排查定位线上问题以及实时运行情况. 搭建流程 安装虚拟输出设备:sud ...

  3. 20145326 《Java程序设计》第6周学习总结

    20145326 <Java程序设计>第6周学习总结 教材学习内容总结 第十章 一.使用InputStream与OutputStream 1.串流设计的概念 想活用输入/输出API,一定要 ...

  4. 解决应用程序无法正常启动0xcxxxxxxxxxx问题

    简述:使用VS2008写了一个MFC程序,结果传到别人的机子上(WIN7)出现应用程序正常初始化(0xc0150002)失败的问题.为什么我的机子上可以,而别人的机子上运行不了呢?下面是我找到的一个解 ...

  5. [BZOJ3237]连通图

    Description Input Output Sample Input 4 5 1 2 2 3 3 4 4 1 2 4 3 1 5 2 2 3 2 1 2 Sample Output Connec ...

  6. sql server timeout

    SqlConnection.ConnectionTimeout https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sq ...

  7. js的重载

    1.重载 //重载(个数不同,类型不同)function prop(){var firstP = document.getElementById("p");if(arguments ...

  8. SharePoint研究之表单登录配置

    本文将演示SharePoint怎样配置表单(Form)登录,后续文章将研究 无密码登录.编程添加用户组.编程添加用户.编程添加文件夹.编程分享文件夹(权限分配)等. 知识点:SharePoint.Sq ...

  9. BZOJ 3876 【AHOI2014】 支线剧情

    题目链接:支线剧情 这道题就是一道裸裸的上下界网络流……只不过这道题边带了权,那么建出图之后跑费用流即可. 首先需要新建超级源\(S\)和超级汇\(T\).对于这道题,对于一条边\((u,v,z)\) ...

  10. 97. Interleaving String *HARD* -- 判断s3是否为s1和s2交叉得到的字符串

    Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. For example,Given:s1 = ...