一、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. }

三、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包中的其他类总结的更多相关文章

  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. Sybase数据库常用sql语言

    Sybase数据库常用sql语言 1,表备份: --table_name1:需要备份的表; table_name2:备份后的表 SELECT * into table_name2 from table ...

  2. Sublime Text 3 配置Python3.x

    Sublime Text 3 配置Python3.x 一.Package Control 安装: 1,通过快捷键 ctrl+` 或者 View > Show Console 打开控制台,然后粘贴 ...

  3. s3c2440中U-boot移植时执行cp.b提示:Flash not Erased【转】

    本文转载自:https://blog.csdn.net/baiyang139/article/details/79054415 版权声明:本文为博主原创文章,未经博主允许不得转载. https://b ...

  4. Vmware 设置NAT模式

    NAT模式,就是让虚拟系统借助NAT(网络地址转换)功能,通过宿主机器所在的网络来访问公网.也就是说,使用NAT模式可以实现在虚拟系统里访问互联网. NAT模式下的虚拟系统的TCP/IP配置信息是由V ...

  5. LINQ 学习路程 -- 查询操作 GroupBy ToLookUp

    Grouping Operators Description GroupBy GroupBy操作返回根据一些键值进行分组,每组代表IGrouping<TKey,TElement>对象 To ...

  6. redis的过期策略以及内存淘汰机制

    redis采用的是定期删除+惰性删除策略. 为什么不用定时删除策略? 定时删除,用一个定时器来负责监视key,过期则自动删除.虽然内存及时释放,但是十分消耗CPU资源.在大并发请求下,CPU要将时间应 ...

  7. [原][osgearth]osgearthviewer读取earth文件,代码解析(earth文件读取的一帧)

    跑osgearthviewer程序 使用一个earth文件做参数传入 跟进代码. 首先osgearthviewer程序加载earth的方式分为两种: 1.根据earth文件(load方式) 2.使用S ...

  8. java线程中的interrupt,isInterrupt,interrupted方法

    在java的线程Thread类中有三个方法,比较容易混淆,在这里解释一下 (1)interrupt:置线程的中断状态 (2)isInterrupt:线程是否中断 (3)interrupted:返回线程 ...

  9. git入门篇

    git是一个分布式版本管理软件,总之是一个软件. github是一个代码托管平台,总之是一个网站. github这个网站使用git这个版本管理软件来托管代码. 相当于本地.公司服务器.Github网站 ...

  10. numpy.zeros(np.zeros)使用方法--python学习笔记31

    https://blog.csdn.net/qq_26948675/article/details/54318917