IO包中的其他类总结
一、PrintStream和PrintWriter
PrintStream
为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
PrintStream
打印的所有字符都使用平台的默认字符编码转换为字节。
在需要写入字符而不是写入字节的情况下,应该使用
类。PrintWriter
1 /** 2 * PrintStream 3 * 1.提供了打印方法,可以对多种类型值进行打印,并保持数据的原有格式 4 * 2.它不抛IOException 5 * 6 * 构造函数 接受三种类型的值 7 * 1.字符串路径 8 * 2.File对象 9 * 2.字符输出流 10 */ 11 public class PrintStreamDemo { 12 13 public static void main(String[] args) throws IOException { 14 PrintStream out=new PrintStream("print.txt"); 15 out.write(97);//a 特点:只保留数最低的八位 16 out.write(610);//a 17 out.print(97);//97 特点:将数据先转成String类型,再打印出来 18 } 19 }
1 /** 2 * PrintWriter:字符打印流 3 * 构造方法参数: 4 * 1.字符串路径 5 * 2.File对象 6 * 3.字节输出流 7 * 4.字符输出流 8 */ 9 public class PrintWriterDemo { 10 11 public static void main(String[] args) throws IOException { 12 BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));//读取流 13 //字符写入流 14 PrintWriter pw=new PrintWriter(new FileWriter("out.txt"),true);//自动刷新 15 String line=null; 16 while((line=bufr.readLine())!=null){ 17 if(line.equals("over")){ 18 break; 19 } 20 pw.println(line.toUpperCase()); 21 } 22 pw.close(); 23 bufr.close(); 24 } 25 }
二、ObjectOutputStream和ObjectInputStream以及Serializable接口
ObjectOutputStream为了延长对象的生命周期,把对象序列化存储到硬盘的文件中,写入的对象必须实现Serializable接口;
ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化
writeObject 方法用于将对象写入流中。所有对象(包括 String 和数组)都可以通过 writeObject 写入。
可将多个对象或基元写入流中。必须使用与写入对象时相同的类型和顺序从相应 ObjectInputstream 中读回对象。
readObject
方法用于从流读取对象。应该使用 Java 的安全强制转换来获取所需的类型。
在 Java 中,字符串和数组都是对象,所以在序列化期间将其视为对象。读取时,需要将其强制转换为期望的类型
1 public class ObjectStreamDemo { 2 3 public static void main(String[] args) throws IOException, ClassNotFoundException { 4 writeObjectDemo(); 5 readObjectDemo(); 6 } 7 8 public static void readObjectDemo() throws IOException, ClassNotFoundException { 9 //ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。 10 ObjectInputStream ois=new ObjectInputStream(new FileInputStream("out.object")); 11 Person p=(Person)ois.readObject(); 12 Person p2=(Person)ois.readObject(); 13 System.out.println(p.getName()+"::"+p.getAge());//花蝴蝶::12 14 System.out.println(p2.getName()+"::"+p2.getAge());//大脸猫::2 15 } 16 17 public static void writeObjectDemo() throws IOException, FileNotFoundException { 18 ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("out.object")); 19 oos.writeObject(new Person("花蝴蝶",12)); 20 oos.writeObject(new Person("大脸猫",2)); 21 oos.close(); 22 } 23 }
* Serializable接口可以为被序列化的类提供类ID号
* 来判断存储的对象和类是否是同一个版本
* 如果ID号不同的话,会发生InvaildClassException异常
*
* transient:如果一个属性不是静态化的,但又不想被序列化存储,就可以用这个关键字修饰
下面是实现了Serializable接口的Person类的代码:
![](/assets/blank.gif)
![](/assets/blank.gif)
1 package www.brighten.io; 2 3 import java.io.Serializable; 4 5 public class Person implements Serializable { 6 /** 7 * Serializable接口可以为被序列化的类提供类ID号 8 * 来判断存储的对象和类是否是同一个版本 9 * 如果ID号不同的话,会发生InvaildClassException异常 10 * 11 * transient:如果一个属性不是静态化的,但又不想被序列化存储,就可以用这个关键字修饰 12 */ 13 private static final long serialVersionUID = 3221L; 14 private transient String name; 15 private static int age; 16 public Person(String name, int age) { 17 super(); 18 this.name = name; 19 this.age = age; 20 } 21 public String getName() { 22 return name; 23 } 24 public void setName(String name) { 25 this.name = name; 26 } 27 public int getAge() { 28 return age; 29 } 30 public void setAge(int age) { 31 this.age = age; 32 } 33 34 }
View Code
三、RandomAccessFile
此类的实例支持对随机访问文件的读取和写入。
随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。
存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。
* RandomAccessFile这个类从名字就可以看出,
* 不是IO体系总的子类,它的父类是Object
* 特点:
* 1.既能读,又能写。
* 2.该对象内部维护了一个大型byte数组,可以通过指针对数组元素进行操作
* 3.可以通过getFilePointer获取指针;通过seek方法设置指针位置
* 4.其实该对象就是对字节输入流和输出流进行了封装
* 5.该对象的源或者目的只能是文件,通过构造方法可以看出。
1 package www.brighten.io; 2 3 import java.io.File; 4 import java.io.FileNotFoundException; 5 import java.io.IOException; 6 import java.io.RandomAccessFile; 7 8 public class RandomAccessFileDemo { 9 10 public static void main(String[] args) throws IOException { 11 writeFiles(); 12 randomWrite(); 13 readFiles(); 14 } 15 public static void randomWrite() throws IOException { 16 RandomAccessFile raf=new RandomAccessFile("randomFile.txt", "rw"); 17 raf.seek(3*8); 18 /** 19 * 可以让不同的线程对不同的部分进行写入 20 * 应用如断点续传 21 */ 22 raf.write("爱新觉罗溥仪".getBytes()); 23 raf.writeInt(22); 24 raf.close(); 25 26 } 27 public static void readFiles() throws IOException { 28 RandomAccessFile raf=new RandomAccessFile("randomFile.txt", "rw"); 29 //用seek方法设置指针的位置,直接读取第二个人的信息 30 raf.seek(8); 31 byte[] buf=new byte[4]; 32 raf.read(buf); 33 String name=new String(buf); 34 35 int age=raf.readInt(); 36 System.out.println("name="+name);//name=杜甫 37 System.out.println("age="+age);//age=99 38 39 raf.close(); 40 } 41 //使用RandomAccessFile写入一些人员信息,比如,姓名和年龄 42 public static void writeFiles() throws IOException { 43 /** 44 * IO流不同,存不存在,都会创建 45 * RandomAccessFile,如果文件不存在,则创建;如果文件存在,就不创建 46 */ 47 RandomAccessFile raf=new RandomAccessFile(new File("randomFile.txt"), "rw"); 48 raf.write("李白".getBytes() ); 49 raf.writeInt(97); 50 raf.write("杜甫".getBytes() ); 51 raf.writeInt(99); 52 raf.close(); 53 } 54 }
四、PipedInputStream和PipedOutputStream
管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。
通常,数据由某个线程从 PipedInputStream
对象读取,并由其他线程将其写入到相应的 PipedOutputStream
。
不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。
1 public class PipedStream { 2 3 public static void main(String[] args) throws IOException { 4 PipedInputStream in=new PipedInputStream(); 5 PipedOutputStream out=new PipedOutputStream(); 6 in.connect(out);//管道读取流和写入流相连接 7 new Thread(new Input(in)).start(); 8 new Thread(new Output(out)).start(); 9 } 10 } 11 class Input implements Runnable{ 12 private PipedInputStream in; 13 public Input(PipedInputStream in){ 14 this.in=in; 15 } 16 @Override 17 public void run() { 18 byte[] buf=new byte[1024]; 19 int len; 20 try { 21 len = in.read(buf); 22 String str=new String(buf,0,len); 23 System.out.println(str); 24 } catch (IOException e) { 25 // TODO Auto-generated catch block 26 e.printStackTrace(); 27 } 28 } 29 } 30 31 class Output implements Runnable{ 32 private PipedOutputStream out; 33 public Output(PipedOutputStream out){ 34 this.out=out; 35 } 36 @Override 37 public void run() { 38 try { 39 Thread.sleep(3000); 40 out.write("Hello,管道流来了!".getBytes()); 41 } catch (Exception e) { 42 e.printStackTrace(); 43 } 44 } 45 }
五、DataInputStream和DataOutputStream
数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。
数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入。
1 public class DataStreamDemo { 2 3 public static void main(String[] args) throws IOException { 4 writeDemo(); 5 readDemo(); 6 } 7 8 public static void readDemo() throws IOException { 9 DataInputStream dis=new DataInputStream(new FileInputStream("data.txt")); 10 String str=dis.readUTF(); 11 dis.close(); 12 System.out.println(str); 13 } 14 15 public static void writeDemo() throws IOException { 16 DataOutputStream dos=new DataOutputStream(new FileOutputStream("data.txt")); 17 dos.writeUTF("世界,你好!"); 18 dos.close(); 19 } 20 }
六、以ByteArrayInputStream为代表的类
ByteArrayInputStream
包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪 read
方法要提供的下一个字节。
关闭 ByteArrayInputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。
特点:源和目的都是内存
类似的类有CharArrayReader 、CharArrayWriter、StringReader、 StringWriter。
1 public class ByteArrayStreamDemo { 2 public static void main(String[] args) { 3 ByteArrayInputStream bais=new ByteArrayInputStream("Hello World!".getBytes()); 4 ByteArrayOutputStream baos=new ByteArrayOutputStream(); 5 int ch=0; 6 while((ch=bais.read())!=-1){ 7 baos.write(ch); 8 } 9 System.out.println(baos.toString());//Hello World! 10 } 11 }
七、编码问题(解码错误的补救方法和联通问题)
开发常用的编码有GBK、utf-8
* 字符串-->字节数组:编码
* 字节数组-->字符串:解码
* 你好的GBK编码:-60 -29 -70 -61
* 你好的UTF-8编码:-28 -67 -96 -27 -91 -67
1 public class EncodeDemo { 2 3 public static void main(String[] args) throws UnsupportedEncodingException { 4 //demo1(); 5 demo2(); 6 } 7 8 /** 9 * 如果你编错了,肯定解不出来 10 如果解错了,可能还有办法补救 11 */ 12 public static void demo1() throws UnsupportedEncodingException { 13 String str=new String("自律给我自由"); 14 //编码 15 byte[] buf=str.getBytes("GBK"); 16 //printBytes(buf); 17 //解码 18 String s1=new String(buf,"iso8859-1"); 19 System.out.println("s1="+s1);//s1=×???????×??? 20 21 //解码错误,补救方法 22 byte[] buf2=s1.getBytes("iso8859-1");//获取源字节 23 String s2=new String(buf2,"GBK"); 24 System.out.println("s2="+s2);//s2=自律给我自由 25 } 26 /** 27 * 补救失败,因为按照GBK编码得到的字节在utf-8中无法查到对应数据,就用了别的字符替代 28 * 这样再次解码成字节后,已经不是原来的字节数组了 29 * 特例:“谢谢”可以。 30 * 所以说“解码错了,可能还有方法补救” 31 * @throws UnsupportedEncodingException 32 */ 33 public static void demo2() throws UnsupportedEncodingException { 34 String str=new String("举杯邀明月"); 35 byte[] buf=str.getBytes("gbk"); 36 printBytes(buf);//-66 -39 -79 -83 -47 -5 -61 -9 -44 -62 37 38 String s1=new String(buf,"utf-8"); 39 System.out.println("s1="+s1); 40 41 //用demo1中的方法补救 42 byte[] buf2=s1.getBytes(); 43 printBytes(buf2);//63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 44 String s2=new String(buf2,"gbk"); 45 System.out.println("s2="+s2); 46 } 47 48 public static void printBytes(byte[] buf) { 49 for(byte b:buf){ 50 System.out.print(b+" "); 51 } 52 System.out.println(); 53 } 54 }
* 有一个让人疑惑的现象。
* 用Windows记事本新建一个文件,在里面写上“联通”两字
* 保存以后再打开,就会看到"��ͨ",这种很奇怪的字符,
* 下面的程序就来分析一下原因。
* 运行程序后可以得到“联通”的GBK编码的字节是
11000001
10101010
11001101
10101000
开头依次是110、10、110、110;正好也符合utf-8两个字节一个字符的编码特点,
所以记事本就以utf-8的规则进行解码了,而没用GBK解码,所以出现了乱码
1 public class LianTongBug { 2 3 public static void main(String[] args) throws IOException { 4 String str=new String("联通"); 5 byte[] buf=str.getBytes("gbk"); 6 for(byte b:buf){ 7 System.out.println(Integer.toBinaryString(b&255));//只取后八位 8 } 9 } 10 }
IO包中的其他类总结相关推荐
- Java.io包中常用的类
Java.io包 Java.io.BufferedInputStream类实例 Java.io.BufferedOutputStream类使用例子 Java.io.BufferedReader类 Ja ...
- java.io包对象读写_java.io 包中的____________和____________类主要用于对对象(Object)的读写_学小易找答案...
[多选题]连铸钢水成分控制的要求有( ). [单选题]起动机用直流电动机将电能转化为 [单选题]下列关于我国少数民族传统禁忌的说法中,错误的是( ). [多选题]下列选项中 , 属于表单控件的是 ( ...
- java中常用的包、类、以及包中常用的类、方法、属性----sql和text\swing
java中常用的包.类.以及包中常用的类.方法.属性 常用的包 java.io.*; java.util.*; java.lang.*; java.sql.*; java.text.*; java.a ...
- java面试题43要使某个类能被同一个包中的其他类访问,但不能被这个包以外的类访问,可以( )
java面试题43要使某个类能被同一个包中的其他类访问,但不能被这个包以外的类访问,可以( ) A让该类不使用任何关键字 B使用private关键字 C 使用protected关键字 D 使用void ...
- 同包类 和 其他类 java_关于继承:为什么Java中的“protected”修饰符允许访问同一个包中的其他类?...
在Java中,具有"受保护"修饰符的成员不仅可以由同一个类和子类访问,还可以由同一个包中的每个人访问? 我想知道语言设计的原因,而不是实际的应用程序(例如,测试) +1坦率地说我也 ...
- (35)System Verilog引用包中定义的类(成功)
(35)System Verilog引用包中定义的类(成功) 1.1 目录 1)目录 2)FPGA简介 3)System Verilog简介 4)System Verilog引用包中定义的类(成功) ...
- (34)System Verilog引用包中定义的类(失败)
(34)System Verilog引用包中定义的类(失败) 1.1 目录 1)目录 2)FPGA简介 3)System Verilog简介 4)System Verilog引用包中定义的类(失败) ...
- apache的IO包中的FileUtils方法的使用
首先非常感谢apache这个公司给我们免费开源了这个IO包,我们才能学习使用开发出我们想要的产品,知道这个包已经很多年了一直都是在用固定的几个方法,对里面很多方法都不会用,今天有空我就来研究试用下这里 ...
- Java.math包中常用的类
Java.math包 Java.math.BigDecimal类 Java.math.BigInteger类实例 Java.math.MathContext类实例
最新文章
- 腾讯推出的这款高性能 RPC 开发框架,确定不了解下吗?
- [转载]hadoop集群默认配置和常用配置
- 使用python获取路径问题
- 关于js里的document.compatmode
- 工程优化作业——成功失败法和黄金分割法
- kafka reassign 限速_RabbitMQ 七战 Kafka,差异立现!
- 多个html如何套用套一个头部,Vue.js项目中管理每个页面的头部标签的两种方法...
- VS2010/VS2012/VS2015下openGL环境配置(转)
- 36.软件安装:RPM,SRPM和YUM功能
- 数据过多,程序运行失败
- Ubuntu Thinkphp page not found
- Python反编译apk,获取各类信息
- 征集对智能视觉组eIQ的使用反馈
- 数据大屏之跑马灯功能
- cloudchat苹果如何下载只能通过ipa吗
- 一篇关于编程的文章,启发你的编程知识
- Python代码写好了怎么运行?
- android指南针校准 代码_android 指南针app源码(亲测可用)
- 解决win10内存占用逐渐变大(亲测有效)
- html翻译插件,vscode系列: 做个五脏俱全的翻译插件