IO包中的其他类总结
一、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包中的其他类总结的更多相关文章
- 黑马程序员——【Java基础】——File类、Properties集合、IO包中的其他类
---------- android培训.java培训.期待与您交流! ---------- 一.File类 (一)概述 1.File类:文件和目录路径名的抽象表现形式 2.作用: (1)用来将文件或 ...
- Java基础---IO(三)--IO包中的其他类
第一讲 对象序列化 一.概述 将堆内存中的对象存入硬盘,保留对象中的数据,称之为对象的持久化(或序列化).使用到的两个类:ObjectInputStream和ObjectOutputStrea ...
- IO包中的RandomAccessFile类
RandomAccessFile RandomAccessFile 是随机访问文件的类.它支持对文件随机访问的读取和写入,即我们也可以从指定的位置读取/写入文件数据,因为该类在其内部封装了一个数组和指 ...
- IO包中的其他类
查看各对象API文档 打印流 PrintWriter PrintStream 序列流:对多个流进行排列合并 SequenceInputStream public static void main(St ...
- Java笔记(二十八)……IO流下 IO包中其他常用类以及编码表问题
PrintWriter打印流 Writer的子类,既可以接收字符流,也可以接收字节流,还可以接收文件名或者文件对象,非常方便 同时,还可以设置自动刷新以及保持原有格式写入各种文本类型的print方法 ...
- IO 包中的其他类
打印流 PrintWriter 和 PrintWriter 直接操作输入流和文件 序列流 SequenceInputStream 对多个输入流进行合并 操作对象 ObjectInputStream 和 ...
- Java之IO(十四)IO包中其它类
转载请注明出处:http://www.cnblogs.com/lighten/p/7267553.html 1.前言 此章介绍IO包中剩余未介绍的几个流和工具类,包括LineNumberReader. ...
- java.io包中的字节流—— FilterInputStream和FilterOutputStream
接着上篇文章,本篇继续说java.io包中的字节流.按照前篇文章所说,java.io包中的字节流中的类关系有用到GoF<设计模式>中的装饰者模式,而这正体现在FilterInputStre ...
- Java IO流中的File类学习总结
一.File类概述 File类位于java.io包中,是对文件系统中文件以及文件夹进行封装的对象,可以通过对象的思想来操作文件和文件夹. File类有多种重载的构造方法.File类保存文件或目录的各种 ...
随机推荐
- HttpClient发送get,post接口请求
HttpClient发送get post接口请求/* * post * @param url POST地址 * @param data POST数据NameValuePair[] * @retur ...
- python16_day35【算法】
一.BTree class BinTreeNode: def __init__(self, data): self.data = data self.lchild = None self.rchild ...
- flask后端 获取不到form表单post 的文件
原文地址http://docs.jinkan.org/docs/flask/patterns/fileuploads.html <form> 标签被标记有 enctype=multipar ...
- 通过自动回复机器人学Mybatis:MySQL脚本 + db >> dao >> service >> servlet
留着参考 makeData.sql delimiter // create procedure make_data() begin declare i int ; do insert into mes ...
- Python笔记 #04# Methods
源:DataCamp datacamp 的 DAILY PRACTICE + 日常收集. Methods String Methods List Methods 缺一 Methods You can ...
- 常用php操作redis命令整理(三)LIST类型
LIST 头元素和尾元素:头元素指的是列表左端/前端第一个元素,尾元素指的是列表右端/后端第一个元素.举个例子,列表list包含三个元素:x, y, z,其中x是头元素,而z则是尾元素.空列表:指不包 ...
- 20145219《网络对抗》Web安全基础实践
20145219<网络对抗>Web安全基础实践 基础问题回答 SQL注入攻击原理,如何防御? 原理:SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL ...
- ESXi主机遗忘密码重置密码
ESXi版本:6.0.0 VMware-VMvisor-Installer-6.0.0.update02-3620759.x86_64-Dell_Customized-A00.iso 使用和服务器系统 ...
- IntelliJ IDEA 常用快捷键,maven依赖图,个性化设置,禁用Search Everywhere
查看idea 中jar关系图 快捷键: Ctrl+/ 用于注释,取消注释 Ctrl+Shift+F 全文搜索 Ctrl+F 单页面查找 Ctrl+Alt+Shift+L 格式化代码 ======== ...
- HDU 2222 Keywords Search(AC自动机)题解
题意:给你几个keywords,再给你一段文章,问你keywords出现了几次. 思路:这里就要用到多模匹配算法AC自动机了,AC自动机需要KMP和字典树的知识,匹配时是在字典树上,失配我们就要用到类 ...