一、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. JavaScript修改CSS属性的实例代码

    用原生的javascript修改CSS属性的方法. 用JavaScript修改CSS属性 只有写原生的javascript了.  1.用JS修改标签的 class 属性值:  class 属性是在标签 ...

  2. 爬虫概要及web微信请求分析

    一.爬虫概要 1.网络爬虫是什么 百度百科:网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常 ...

  3. RabbitMQ 一个demo

    Code: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Sy ...

  4. CentOS7.2 安装Redis3.2.8

    Redis3.2.8 下载 下载Redis3.2.8.tar.gz 将文件放置在usr/local/redis/中 解压文件 安装: make && make install [roo ...

  5. [SpringBoot] - 配置文件的多种形式及JSR303数据校验

    Springboot配置文件: application.yml   application.properties(自带) yml的格式写起来稍微舒服一点 在application.properties ...

  6. MySQL —— 基本查询方法

    MySQL —— 简单查询与按条件查询 在MySQL中从数据表中查询数据的基本语句时select语句.  select语句基本语法格式:      select 查询内容       from 表名  ...

  7. python学习笔记(自定义库文件路径)

    博主最近在弄接口自动化.主要是基于python自带的unittest框架.包括 Pubilc模块定义所有接口. Main模块根据业务需求重新封装接口便于测试. config文件导入测试业务的固定参数. ...

  8. IntelliJ IDEA自定义类和方法注解模板

    现在Java开发主流工具应该是Intelij Idea 方便快捷. 本文将主要介绍如何用Intelij Idea配置类及方法的注释模板提高代码注释效率 1. 配置类注解模板 找到配置页面 File - ...

  9. Android Studio 中实现高德定位并获取相应信息

    Android开发项目时常常会遇到定位这个功能,所以写了这篇博客,今天主要讲的高德地图的定位并获取相应信息. 首先导入高德的jar包 选中jar包右键点击  Add As Library, 在buil ...

  10. Linux命令详解-install

    install命令的作用是安装或升级软件或备份数据,它的使用权限是所有用户. 1.命令格式: (1)install [选项]... 来源 目的地 (2)install [选项]... 来源... 目录 ...