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类保存文件或目录的各种 ...
随机推荐
- 数据挖掘-逻辑Logistic回归
逻辑回归的基本过程:a建立回归或者分类模型--->b 建立代价函数 ---> c 优化方法迭代求出最优的模型参数 --->d 验证求解模型的好坏. 1.逻辑回归模型: 逻辑回归(L ...
- VS2010/MFC编程入门之十六(对话框:消息对话框)
前面几节鸡啄米讲了属性页对话框,我们可以根据所讲内容方便的建立自己的属性页对话框.本节讲解Windows系统中最常用最简单的一类对话框--消息对话框. 我们在使用Windows系统的过程中经常会见到消 ...
- BZOJ 5102: [POI2018]Prawnicy
考虑最优解的集合中一定有一个$l$最大的,我们就去枚举左端点,把所有$l$小于等于它的全丢进堆里,取前$k$个即可. #include <bits/stdc++.h> using name ...
- ng-深度学习-课程笔记-11: 卷积神经网络(Week1)
1 边缘检测( edage detection ) 下图是垂直边缘检测的例子,实际上就是用一个卷积核进行卷积的过程. 这个例子告诉我们,卷积可以完成垂直方向的边缘检测.同理卷积也可以完成水平方向的边缘 ...
- javascript 快速排序方法
"快速排序"的思想很简单,整个排序过程只需要三步: (1)在数据集之中,选择一个元素作为"基准"(pivot). (2)所有小于"基准"的元 ...
- 初学libcurl
最近想把某网站上的些数据download下来,在网上找到了cURL,正好来边学边弄一下! 下载libcurl源代码 cURL的官网是http://curl.haxx.se/ ,直接下载源代码包来编译吧 ...
- Spring Data JPA中CrudRepository与JpaRepository的不同
使用Spring Data JPA CrudRepository 和JpaRepository 的好处: 继承这些接口,可以使Spring找到自定义的数据库操作接口,并生成代理类,后续可以注入到Spr ...
- QT+VS中ui不能声明为指针?
问题描述:QtCreator里的UI全是默认为指针类型,调用的时候[ui->]但是使用VS+Qt来,发来默认的是变量类型,使用的时候[ui.] 统一:为了统一我把后者声明改为前者 问题:在mai ...
- LINQ 学习路程 -- 查询操作 GroupBy ToLookUp
Grouping Operators Description GroupBy GroupBy操作返回根据一些键值进行分组,每组代表IGrouping<TKey,TElement>对象 To ...
- BZOJ 1566 【NOI2009】 管道取珠
题目链接:管道取珠 这道题思路还是很巧妙的. 一开始我看着那个平方不知所措……看了题解后发现,这种问题有一类巧妙的转化.我们可以看成两个人来玩这个游戏,那么答案就是第二个人的每个方案在第一个人的所有方 ...