热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

IO包中的其他类总结

一、PrintStream和PrintWriterPrintStream为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。PrintStream打印的所有字符都使用平台的默认

一、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类的代码:

 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 }

 


推荐阅读
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
author-avatar
mobiledu2502878157
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有