初学java,一直搞不懂java里面的io关系,在网上找了很多大多都是给个结构图草草描述也看的不是很懂。而且没有结合到java7 的最新技术,所以自己来整理一下,有错的话请指正,也希望大家提出宝贵意见。

首先看个图:(如果你也是初学者,我相信你看了真个人都不好了,想想java设计者真是煞费苦心啊!)

这是java io 比较基本的一些处理流,除此之外我们还会提到一些比较深入的基于io的处理类,比如console类,SteamTokenzier,Externalizable接口,Serializable接口等等一些高级用法极其原理。

一、java io的开始:文件

1. 我们主要讲的是流,流的本质也是对文件的处理,我们循序渐进一步一步从文件将到流去。

2. java 处理文件的类 File,java提供了十分详细的文件处理方法,举了其中几个例子,其余的可以去

  1. package com.hxw.io;
  2. import java.io.*;
  3. public class FileExample{
  4. public static void main(String[] args) {
  5. createFile();
  6. }
  7. /**
  8. * 文件处理示例
  9. */
  10. public static void createFile() {
  11. File f=new File("E:/电脑桌面/jar/files/create.txt");
  12. try{
  13. f.createNewFile();  //当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。
  14. System.out.println("该分区大小"+f.getTotalSpace()/(1024*1024*1024)+"G"); //返回由此抽象路径名表示的文件或目录的大小。
  15. f.mkdirs();  //创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。
  16. //            f.delete(); //  删除此抽象路径名表示的文件或目录
  17. System.out.println("文件名  "+f.getName());  //  返回由此抽象路径名表示的文件或目录的名称。
  18. System.out.println("文件父目录字符串 "+f.getParent());// 返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。
  19. }catch (Exception e) {
  20. e.printStackTrace();
  21. }
  22. }
  23. }

二、字节流:

1.字节流有输入和输出流,我们首先看输入流InputStream,我们首先解析一个例子(FileInputStream)。

  1. package com.hxw.io;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. public class FileCount {
  7. /**
  8. * 我们写一个检测文件长度的小程序,别看这个程序挺长的,你忽略try catch块后发现也就那么几行而已。
  9. */
  10. publicstatic void main(String[] args) {
  11. //TODO 自动生成的方法存根
  12. int count=0;  //统计文件字节长度
  13. InputStreamstreamReader = null;   //文件输入流
  14. try{
  15. streamReader=newFileInputStream(new File("D:/David/Java/java 高级进阶/files/tiger.jpg"));
  16. /*1.new File()里面的文件地址也可以写成D:\\David\\Java\\java 高级进阶\\files\\tiger.jpg,前一个\是用来对后一个
  17. * 进行转换的,FileInputStream是有缓冲区的,所以用完之后必须关闭,否则可能导致内存占满,数据丢失。
  18. */
  19. while(streamReader.read()!=-1) {  //读取文件字节,并递增指针到下一个字节
  20. count++;
  21. }
  22. System.out.println("---长度是: "+count+" 字节");
  23. }catch (final IOException e) {
  24. //TODO 自动生成的 catch 块
  25. e.printStackTrace();
  26. }finally{
  27. try{
  28. streamReader.close();
  29. }catch (IOException e) {
  30. //TODO 自动生成的 catch 块
  31. e.printStackTrace();
  32. }
  33. }
  34. }
  35. }

我们一步一步来,首先,上面的程序存在问题是,每读取一个自己我都要去用到FileInputStream,我输出的结果是“---长度是: 64982

字节”,那么进行了64982次操作!可能想象如果文件十分庞大,这样的操作肯定会出大问题,所以引出了缓冲区的概念。可以将
streamReader.read()改成streamReader.read(byte[]b)此方法读取的字节数目等于字节数组的长度,读取的数据
被存储在字节数组中,返回读取的字节数,InputStream还有其他方法mark,reset,markSupported方法,例如:

markSupported 判断该输入流能支持mark 和 reset 方法。

mark用于标记当前位置;在读取一定数量的数据(小于readlimit的数据)后使用reset可以回到mark标记的位置。

FileInputStream不支持mark/reset操作;BufferedInputStream支持此操作;

mark(readlimit)的含义是在当前位置作一个标记,制定可以重新读取的最大字节数,也就是说你如果标记后读取的字节数大于readlimit,你就再也回不到回来的位置了。

通常InputStream的read()返回-1后,说明到达文件尾,不能再读取。除非使用了mark/reset。

2.FileOutputStream 循序渐进版, OutputStream是所有字节输出流的父类,子类有
ByteArrayOutputStream,FileOutputStream,ObjectOutputStreanm,这些我们在后面都会一一说
到。先说FileOutputStream

我以一个文件复制程序来说,顺便演示一下缓存区的使用。(Java
I/O默认是不缓冲流的,所谓“缓冲”就是先把从流中得到的一块字节序列暂存在一个被称为buffer的内部字节数组里,然后你可以一下子取到这一整块的
字节数据,没有缓冲的流只能一个字节一个字节读,效率孰高孰低一目了然。有两个特殊的输入流实现了缓冲功能,一个是我们常用的
BufferedInputStream.)

  1. package com.hxw.io;
  2. import java.io.*;
  3. public class FileCopy {
  4. public static void main(String[] args) {
  5. // TODO自动生成的方法存根
  6. byte[] buffer=new byte[512];   //一次取出的字节数大小,缓冲区大小
  7. int numberRead=0;
  8. FileInputStream input=null;
  9. FileOutputStream out =null;
  10. try {
  11. input=new FileInputStream("D:/David/Java/java 高级进阶/files/tiger.jpg");
  12. out=new FileOutputStream("D:/David/Java/java 高级进阶/files/tiger2.jpg"); //如果文件不存在会自动创建(目录不存在会报错)
  13. while ((numberRead=input.read(buffer))!=-1) {  //numberRead的目的在于防止最后一次读取的字节小于buffer长度,
  14. out.write(buffer, 0, numberRead);       //否则会自动被填充0
  15. }
  16. } catch (final IOException e) {
  17. // TODO自动生成的 catch 块
  18. e.printStackTrace();
  19. }finally{
  20. try {
  21. input.close();
  22. out.close();
  23. } catch (IOException e) {
  24. // TODO自动生成的 catch 块
  25. e.printStackTrace();
  26. }
  27. }
  28. }
  29. }

3.读写对象:ObjectInputStream 和ObjectOutputStream
,该流允许读取或写入用户自定义的类,但是要实现这种功能,被读取和写入的类必须实现Serializable接口,其实该接口并没有什么方法,可能相当
于一个标记而已,但是确实不可缺少的。实例代码如下:

  1. package com.hxw.io;
  2. import java.io.*;
  3. public class ObjetStream {
  4. /**
  5. * @param args
  6. */
  7. public static void main(String[] args) {
  8. // TODO自动生成的方法存根
  9. ObjectOutputStream objectwriter=null;
  10. ObjectInputStream objectreader=null;
  11. try {
  12. objectwriter=new ObjectOutputStream(new FileOutputStream("D:/David/Java/java 高级进阶/files/student.txt"));
  13. objectwriter.writeObject(new Student("gg", 22));
  14. objectwriter.writeObject(new Student("tt", 18));
  15. objectwriter.writeObject(new Student("rr", 17));
  16. objectreader=new ObjectInputStream(new FileInputStream("D:/David/Java/java 高级进阶/files/student.txt"));
  17. for (int i = 0; i < 3; i++) {
  18. System.out.println(objectreader.readObject());
  19. }
  20. } catch (IOException | ClassNotFoundException e) {
  21. // TODO自动生成的 catch 块
  22. e.printStackTrace();
  23. }finally{
  24. try {
  25. objectreader.close();
  26. objectwriter.close();
  27. } catch (IOException e) {
  28. // TODO自动生成的 catch 块
  29. e.printStackTrace();
  30. }
  31. }
  32. }
  33. }
  34. class Student implements Serializable{
  35. private String name;
  36. private int age;
  37. public Student(String name, int age) {
  38. super();
  39. this.name = name;
  40. this.age = age;
  41. }
  42. @Override
  43. public String toString() {
  44. return "Student [name=" + name + ", age=" + age + "]";
  45. }
  46. }

运行后系统输出:

Student [name=gg, age=22]

Student [name=tt, age=18]

Student [name=rr, age=17]

4.有时没有必要存储整个对象的信息,而只是要存储一个对象的成员数据,成员数据的类型假设都是Java的基本数据类型,这样的需求不必
使用到与Object输入、输出相关的流对象,可以使用DataInputStream、DataOutputStream来写入或读出数据。下面是一个
例子:(
DataInputStream的好处在于在从文件读出数据时,不用费心地自行判断读入字符串时或读入int类型时何时将停止,使用对应的readUTF()和readInt()方法就可以正确地读入完整的类型数据。)

  1. package com.hxw;
  2. public class Member {
  3. private String name;
  4. private int age;
  5. public Member() {
  6. }
  7. public Member(String name, int age) {
  8. this.name = name;
  9. this.age = age;
  10. }
  11. public void setName(String name){
  12. this.name = name;
  13. }
  14. public void setAge(int age) {
  15. this.age = age;
  16. }
  17. public String getName() {
  18. return name;
  19. }
  20. public int getAge() {
  21. return age;
  22. }
  23. }

打算将Member类实例的成员数据写入文件中,并打算在读入文件数据后,将这些数据还原为Member对象。下面的代码简单示范了如何实现这个需求。

  1. package com.hxw;
  2. import java.io.*;
  3. public class DataStreamDemo
  4. {
  5. public static void main(String[]args)
  6. {
  7. Member[] members = {newMember("Justin",90),
  8. newMember("momor",95),
  9. newMember("Bush",88)};
  10. try
  11. {
  12. DataOutputStreamdataOutputStream = new DataOutputStream(new FileOutputStream(args[0]));
  13. for(Member member:members)
  14. {
  15. //写入UTF字符串
  16. dataOutputStream.writeUTF(member.getName());
  17. //写入int数据
  18. dataOutputStream.writeInt(member.getAge());
  19. }
  20. //所有数据至目的地
  21. dataOutputStream.flush();
  22. //关闭流
  23. dataOutputStream.close();
  24. DataInputStreamdataInputStream = new DataInputStream(new FileInputStream(args[0]));
  25. //读出数据并还原为对象
  26. for(inti=0;i<members.length;i++)
  27. {
  28. //读出UTF字符串
  29. String name =dataInputStream.readUTF();
  30. //读出int数据
  31. int score =dataInputStream.readInt();
  32. members[i] = newMember(name,score);
  33. }
  34. //关闭流
  35. dataInputStream.close();
  36. //显示还原后的数据
  37. for(Member member : members)
  38. {
  39. System.out.printf("%s\t%d%n",member.getName(),member.getAge());
  40. }
  41. }
  42. catch(IOException e)
  43. {
  44. e.printStackTrace();
  45. }
  46. }
  47. }

5.PushbackInputStream类继承了FilterInputStream类是iputStream类的修饰者。提供可以
将数据插入到输入流前端的能力(当然也可以做其他操作)。简而言之PushbackInputStream类的作用就是能够在读取缓冲区的时候提前知道下
一个字节是什么,其实质是读取到下一个字符后回退的做法,这之间可以进行很多操作,这有点向你把读取缓冲区的过程当成一个数组的遍历,遍历到某个字符的时候可以进行的操作,当然,如果要插入,能够插入的最大字节数是与推回缓冲区的大小相关的,插入字符肯定不能大于缓冲区吧!下面是一个示例。

  1. package com.hxw.io;
  2. import java.io.ByteArrayInputStream; //导入ByteArrayInputStream的包
  3. import java.io.IOException;
  4. import java.io.PushbackInputStream;
  5. /**
  6. * 回退流操作
  7. * */
  8. public class PushBackInputStreamDemo {
  9. public static void main(String[] args) throws IOException {
  10. String str = "hello,rollenholt";
  11. PushbackInputStream push = null; // 声明回退流对象
  12. ByteArrayInputStream bat = null; // 声明字节数组流对象
  13. bat = new ByteArrayInputStream(str.getBytes());
  14. push = new PushbackInputStream(bat); // 创建回退流对象,将拆解的字节数组流传入
  15. int temp = 0;
  16. while ((temp = push.read()) != -1) { // push.read()逐字节读取存放在temp中,如果读取完成返回-1
  17. if (temp == ',') { // 判断读取的是否是逗号
  18. push.unread(temp); //回到temp的位置
  19. temp = push.read(); //接着读取字节
  20. System.out.print("(回退" + (char) temp + ") "); // 输出回退的字符
  21. } else {
  22. System.out.print((char) temp); // 否则输出字符
  23. }
  24. }
  25. }
  26. }

6.SequenceInputStream:有些情况下,当我们需要从多个输入流中向程序读入数据。此时,可以使用合并流,将多个输入
流合并成一个SequenceInputStream流对象。SequenceInputStream会将与之相连接的流集组合成一个输入流并从第一个输
入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。
合并流的作用是将多个源合并合一个源。其可接收枚举类所封闭的多个字节流对象。

  1. package com.hxw.io;
  2. import java.io.*;
  3. import java.util.Enumeration;
  4. import java.util.Vector;
  5. public class SequenceInputStreamTest {
  6. /**
  7. * @param args
  8. *            SequenceInputStream合并流,将与之相连接的流集组合成一个输入流并从第一个输入流开始读取,
  9. *            直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。
  10. *            合并流的作用是将多个源合并合一个源。可接收枚举类所封闭的多个字节流对象。
  11. */
  12. public static void main(String[] args) {
  13. doSequence();
  14. }
  15. private static void doSequence() {
  16. // 创建一个合并流的对象
  17. SequenceInputStream sis = null;
  18. // 创建输出流。
  19. BufferedOutputStream bos = null;
  20. try {
  21. // 构建流集合。
  22. Vector<InputStream> vector = new Vector<InputStream>();
  23. vector.addElement(new FileInputStream("D:\text1.txt"));
  24. vector.addElement(new FileInputStream("D:\text2.txt"));
  25. vector.addElement(new FileInputStream("D:\text3.txt"));
  26. Enumeration<InputStream> e = vector.elements();
  27. sis = new SequenceInputStream(e);
  28. bos = new BufferedOutputStream(new FileOutputStream("D:\text4.txt"));
  29. // 读写数据
  30. byte[] buf = new byte[1024];
  31. int len = 0;
  32. while ((len = sis.read(buf)) != -1) {
  33. bos.write(buf, 0, len);
  34. bos.flush();
  35. }
  36. } catch (FileNotFoundException e1) {
  37. e1.printStackTrace();
  38. } catch (IOException e1) {
  39. e1.printStackTrace();
  40. } finally {
  41. try {
  42. if (sis != null)
  43. sis.close();
  44. } catch (IOException e) {
  45. e.printStackTrace();
  46. }
  47. try {
  48. if (bos != null)
  49. bos.close();
  50. } catch (IOException e) {
  51. e.printStackTrace();
  52. }
  53. }
  54. }
  55. }

7.PrintStream 说这个名字可能初学者不熟悉,如果说System.out.print()你肯定熟悉,System.out这个对象就是PrintStream,这个我们不做过多示例

三、字符流(顾名思义,就是操作字符文件的流)

1.java
使用Unicode存储字符串,在写入字符流时我们都可以指定写入的字符串的编码。前面介绍了不用抛异常的处理字节型数据的流
ByteArrayOutputStream,与之对应的操作字符类的类就是CharArrayReader,CharArrayWriter类,这里也
会用到缓冲区,不过是字符缓冲区,一般讲字符串放入到操作字符的io流一般方法是

CharArrayReaderreader=mew CharArrayReader(str.toCharArray());
一旦会去到CharArrayReader实例就可以使用CharArrayReader访问字符串的各个元素以执行进一步读取操作。不做例子

2.我们用FileReader ,PrintWriter来做示范

  1. package com.hxw.io;
  2. import java.io.FileNotFoundException;
  3. import java.io.FileReader;
  4. import java.io.IOException;
  5. import java.io.PrintWriter;
  6. import java.nio.CharBuffer;
  7. public class Print {
  8. /**
  9. * @param args
  10. */
  11. public static void main(String[] args) {
  12. // TODO自动生成的方法存根
  13. char[] buffer=new char[512];   //一次取出的字节数大小,缓冲区大小
  14. int numberRead=0;
  15. FileReader reader=null;        //读取字符文件的流
  16. PrintWriter writer=null;    //写字符到控制台的流
  17. try {
  18. reader=new FileReader("D:/David/Java/java 高级进阶/files/copy1.txt");
  19. writer=new PrintWriter(System.out);  //PrintWriter可以输出字符到文件,也可以输出到控制台
  20. while ((numberRead=reader.read(buffer))!=-1) {
  21. writer.write(buffer, 0, numberRead);
  22. }
  23. } catch (IOException e) {
  24. // TODO自动生成的 catch 块
  25. e.printStackTrace();
  26. }finally{
  27. try {
  28. reader.close();
  29. } catch (IOException e) {
  30. // TODO自动生成的 catch 块
  31. e.printStackTrace();
  32. }
  33. writer.close();       //这个不用抛异常
  34. }
  35. }
  36. }

3.相对我们前面的例子是直接用FileReader打开的文件,我们这次使用链接流,一般比较常用的都用链接流,所谓链接流就是就多次
对流的封装,这样能更好的操作个管理数据,(比如我们利用
DataInputStream(BufferedInputStream(FileInputStream))将字节流层层包装后,我们可以读取
readByte(),readChar()这样更加具体的操作,注意,该流属于字节流对字符进行操作,)字符流用CharArrayReader就可以
了。下面的示例我们将用到j2se
5中的一个可变参数进行一个小度扩展。使用BufferedWriter
和BufferedReader用文件级联的方式进行写入,即将多个文件写入到同一文件中(自带缓冲区的输出输出流BufferedReader和
BufferedWriter,该流最常用的属readLine()方法了,读取一行数据,并返回String)。

  1. package com.hxw.io;
  2. import java.io.BufferedReader;
  3. import java.io.BufferedWriter;
  4. import java.io.FileReader;
  5. import java.io.FileWriter;
  6. import java.io.IOException;
  7. import java.util.Iterator;
  8. public class FileConcatenate {
  9. /**
  10. * 包装类进行文件级联操作
  11. */
  12. public static void main(String[] args) {
  13. // TODO自动生成的方法存根
  14. try {
  15. concennateFile(args);
  16. } catch (IOException e) {
  17. // TODO自动生成的 catch 块
  18. e.printStackTrace();
  19. }
  20. }
  21. public static voidconcennateFile(String...fileName) throws IOException{
  22. String str;
  23. //构建对该文件您的输入流
  24. BufferedWriter writer=new BufferedWriter(new FileWriter("D:/David/Java/java 高级进阶/files/copy2.txt"));
  25. for(String name: fileName){
  26. BufferedReader reader=new BufferedReader(new FileReader(name));
  27. while ((str=reader.readLine())!=null) {
  28. writer.write(str);
  29. writer.newLine();
  30. }
  31. }
  32. }
  33. }

4.Console类,该类提供了用于读取密码的方法,可以禁止控制台回显并返回char数组,对两个特性对保证安全有作用,平时用的不多,了解就行。

5.StreamTokenizer 类,这个类非常有用,它可以把输入流解析为标记(token), StreamTokenizer

并非派生自InputStream或者OutputStream,而是归类于io库中,因为StreamTokenizer只处理InputStream
对象。

首先给出我的文本文件内容:

'水上漂'

青青草

"i love wyhss"

{3211}

23223 3523

i love wyh ,。

. ,

下面是代码:

  1. package com.hxw.io;
  2. import java.io.BufferedReader;
  3. import java.io.FileReader;
  4. import java.io.IOException;
  5. import java.io.StreamTokenizer;
  6. /**
  7. * 使用StreamTokenizer来统计文件中的字符数
  8. * StreamTokenizer 类获取输入流并将其分析为“标记”,允许一次读取一个标记。
  9. * 分析过程由一个表和许多可以设置为各种状态的标志控制。
  10. * 该流的标记生成器可以识别标识符、数字、引用的字符串和各种注释样式。
  11. *
  12. *  默认情况下,StreamTokenizer认为下列内容是Token: 字母、数字、除C和C++注释符号以外的其他符号。
  13. *  如符号"/"不是Token,注释后的内容也不是,而"\"是Token。单引号和双引号以及其中的内容,只能算是一个Token。
  14. *  统计文章字符数的程序,不是简单的统计Token数就万事大吉,因为字符数不等于Token。按照Token的规定,
  15. *  引号中的内容就算是10页也算一个Token。如果希望引号和引号中的内容都算作Token,应该调用下面的代码:
  16. *    st.ordinaryChar('\'');
  17. * st.ordinaryChar('\"');
  18. */
  19. public class StreamTokenizerExample {
  20. /**
  21. * 统计字符数
  22. * @param fileName 文件名
  23. * @return    字符数
  24. */
  25. public static void main(String[] args) {
  26. String fileName = "D:/David/Java/java 高级进阶/files/copy1.txt";
  27. StreamTokenizerExample.statis(fileName);
  28. }
  29. public static long statis(String fileName) {
  30. FileReader fileReader = null;
  31. try {
  32. fileReader = new FileReader(fileName);
  33. //创建分析给定字符流的标记生成器
  34. StreamTokenizer st = new StreamTokenizer(new BufferedReader(
  35. fileReader));
  36. //ordinaryChar方法指定字符参数在此标记生成器中是“普通”字符。
  37. //下面指定单引号、双引号和注释符号是普通字符
  38. st.ordinaryChar('\'');
  39. st.ordinaryChar('\"');
  40. st.ordinaryChar('/');
  41. String s;
  42. int numberSum = 0;
  43. int wordSum = 0;
  44. int symbolSum = 0;
  45. int total = 0;
  46. //nextToken方法读取下一个Token.
  47. //TT_EOF指示已读到流末尾的常量。
  48. while (st.nextToken() !=StreamTokenizer.TT_EOF) {
  49. //在调用 nextToken 方法之后,ttype字段将包含刚读取的标记的类型
  50. switch (st.ttype) {
  51. //TT_EOL指示已读到行末尾的常量。
  52. case StreamTokenizer.TT_EOL:
  53. break;
  54. //TT_NUMBER指示已读到一个数字标记的常量
  55. case StreamTokenizer.TT_NUMBER:
  56. //如果当前标记是一个数字,nval字段将包含该数字的值
  57. s = String.valueOf((st.nval));
  58. System.out.println("数字有:"+s);
  59. numberSum ++;
  60. break;
  61. //TT_WORD指示已读到一个文字标记的常量
  62. case StreamTokenizer.TT_WORD:
  63. //如果当前标记是一个文字标记,sval字段包含一个给出该文字标记的字符的字符串
  64. s = st.sval;
  65. System.out.println("单词有: "+s);
  66. wordSum ++;
  67. break;
  68. default:
  69. //如果以上3中类型都不是,则为英文的标点符号
  70. s = String.valueOf((char) st.ttype);
  71. System.out.println("标点有: "+s);
  72. symbolSum ++;
  73. }
  74. }
  75. System.out.println("数字有 " + numberSum+"个");
  76. System.out.println("单词有 " + wordSum+"个");
  77. System.out.println("标点符号有: " + symbolSum+"个");
  78. total = symbolSum + numberSum +wordSum;
  79. System.out.println("Total = " + total);
  80. return total;
  81. } catch (Exception e) {
  82. e.printStackTrace();
  83. return -1;
  84. } finally {
  85. if (fileReader != null) {
  86. try {
  87. fileReader.close();
  88. } catch (IOException e1) {
  89. }
  90. }
  91. }
  92. }
  93. }

运行结果为:

标点有: '

单词有: 水上漂

标点有: '

单词有: 青青草

标点有: "

单词有: i

单词有: love

单词有: wyh

单词有: ss

标点有: "

标点有: {

数字有:3211.0

标点有: }

数字有:23223.0

数字有:35.23

单词有: i

单词有: love

单词有: wyh

单词有: ,。

数字有:0.0

标点有: ,

数字有 4个

单词有 10个

标点符号有: 7个

Total= 21

 
5.文件写入和读取(测试代码实例)

public class TestA {
    private String flag;
    
     /**
      * 在执行目标测试方法testTest()前执行
      */
     @Test
     public void testBefore() {
      String str="i love you!";
      FileOutputStream fos = null;
      try {  
          File txt=new File("D:/temp/order.txt");
          if(!txt.exists()){
          txt.createNewFile();
          }
          byte bytes[]=new byte[512];
          bytes=str.getBytes(); //新加的
          int b=str.length(); //改
          fos=new FileOutputStream(txt);
          fos.write(bytes,0,b);
          
         } catch (final IOException e) {  
            // TODO自动生成的 catch 块  
            e.printStackTrace();  
         }finally{  
            try {      
                 fos.close();
            } catch (IOException e) {  
               // TODO自动生成的 catch 块  
               e.printStackTrace();  
            }  
         }
              
            
     }
    
     /**
      * 目标测试方法testTest()
      */
     @Test
     public void testTest() {
         byte[] buffer=new byte[512];   //一次取出的字节数大小,缓冲区大小  
         int numberRead=0;  
         FileInputStream input=null;    
         try {  
            input=new FileInputStream("D:/temp/order.txt");  
             
            while ((numberRead=input.read(buffer))!=-1) {  //numberRead的目的在于防止最后一次读取的字节小于buffer长度,  
                String s = new String(buffer);
                System.out.println(s);       //否则会自动被填充0  
            }  
         } catch (final IOException e) {  
            // TODO自动生成的 catch 块  
            e.printStackTrace();  
         }finally{  
            try {  
               input.close();   
            } catch (IOException e) {  
               // TODO自动生成的 catch 块  
               e.printStackTrace();  
            }  
             
         }  
     }

我们从其中可以看到很多东西:

1.一个单独的小数点“.”是被当做一个数字来对待的,数字的值为0.0;

2.一串汉字只要中间没有符号(空格回车 分号等等)都是被当做一个单词的。中文的标点跟中文的汉字一样处理

3.如果不对引号化成普通字符,一个引号内的内容不论多少都被当做是一个标记。

4.该类能够识别英文标点

6. java
io里面还有其他接口类似Serializable接口的子接口Externalizable接口,比Serializable复杂一些,这里不再介绍。
还有关于java对象版本化的东西感兴趣的可以百度。java nio的东西这里没有涉及,后续会结合到线程再发一篇文章专门解析这个东西。

java IO 实例分析的更多相关文章

  1. java IO实例

    import java.io.*; /** * Created by CLY on 2017/7/23. */ public class Main { public static void main( ...

  2. java grpc实例分析

    一.Protocol Buffer 我们还是先给出一个在实际开发中经常会遇到的系统场景.比如:我们的客户端程序是使用Java开发的,可能运行自不同的平台,如:Linux.Windows或者是Andro ...

  3. java io性能分析

    摘要: 本文大多技术围绕调整磁盘文件 I/O,但是有些内容也同样适合网络 I/O 和窗口输出. 第一部分技术讨论底层的I/O问题,然后讨论诸如压缩,格式化和串行化等高级I/O问题.然而这个讨论没有包含 ...

  4. java IO框架分析

    jave.io框架 2010-11-10 22:18:34|  分类: 默认分类|举报|字号 订阅     可从IO的类层次,IO框架的设计模式来论述. 总体来说,IO可以分为字节流和字符流,不同在于 ...

  5. Java IO流分析整理 .

    Java中的流,可以从不同的角度进行分类. 按照数据流的方向不同可以分为:输入流和输出流. 按照处理数据单位不同可以分为:字节流和字符流. 按照实现功能不同可以分为:节点流和处理流. 输出流: 输入流 ...

  6. JAVA IO分析三:IO总结&文件分割与合并实例

    时间飞逝,马上就要到2018年了,今天我们将要学习的是IO流学习的最后一节,即总结回顾前面所学,并学习一个案例用于前面所学的实际操作,下面我们就开始本节的学习: 一.原理与概念 一.概念流:流动 .流 ...

  7. 许令波老师的java的IO机制分析文章

    深入分析 Java I/O 的工作机制 I/O 问题可以说是当今互联网 Web 应用中所面临的主要问题之一,因为当前在这个海量数据时代,数据在网络中随处流动.这个流动的过程中都涉及到 I/O 问题,可 ...

  8. JAVA IO分析一:File类、字节流、字符流、字节字符转换流

    因为工作事宜,又有一段时间没有写博客了,趁着今天不是很忙开始IO之路:IO往往是我们忽略但是却又非常重要的部分,在这个讲究人机交互体验的年代,IO问题渐渐成了核心问题. 一.File类 在讲解File ...

  9. Java IO 之 FileInputStream & FileOutputStream源码分析

    Writer      :BYSocket(泥沙砖瓦浆木匠) 微         博:BYSocket 豆         瓣:BYSocket FaceBook:BYSocket Twitter   ...

随机推荐

  1. UOJ #78 二分图最大匹配

    #78. 二分图最大匹配 从前一个和谐的班级,有 nl 个是男生,有 nr 个是女生.编号分别为 1,…,nl 和 1,…,nr. 有若干个这样的条件:第 v 个男生和第 u 个女生愿意结为配偶. 请 ...

  2. 【转】Java生成对应字符串的MD5密码模块

    原文网址:http://www.cnblogs.com/xudong-bupt/archive/2013/05/10/3070899.html (1)一般使用的数据库中都会保存用户名和密码,其中密码不 ...

  3. 【模拟】Codeforces 706A Beru-taxi

    题目链接: http://codeforces.com/problemset/problem/706/A 题目大意: 家的坐标在sx,sy,有n辆车,每辆车坐标xi,yi,速度vi,问最快的一辆车什么 ...

  4. websocket nova vnc proxy

    1. vnc proxy的实现原理 vnc 是nova提供的用来访问虚拟机的一项重要功能,用户可以通过websocket来访问,也可以通过java客户端来访问.通过websket访问虚拟机 的功能已经 ...

  5. G - Oil Skimming - hdu 4185(二分图匹配)

    题意:在大海里有一些石油 ‘#’表示石油, ‘.’表示水,有个人有一个工具可以回收这些石油,不过只能回收1*2大小的石油块,里面不能含有海水,要不就没办法使用了,求出来最多能回收多少块石油 分析:先把 ...

  6. K - Transformation-hdu 4578(多操作混合区间更新)线段树

    题意:有四种操作 1,  区间 [l, r] 的值都加上 C 2,  区间 [l, r] 的值都乘上 C 3,  区间 [l, r] 的值都变为C 4,  求区间 [l, r]所有数的p次方的和 分析 ...

  7. iOS利用Runtime自定义控制器POP手势动画

    前言 苹果在iOS 7以后给导航控制器增加了一个Pop的手势,只要手指在屏幕边缘滑动,当前的控制器的视图就会跟随你的手指移动,当用户松手后,系统会判断手指拖动出来的大小来决定是否要执行控制器的Pop操 ...

  8. Python自动化之Django的CSRF

    什么CSRF? CSRF, Cross Site Request Forgery, 跨站点伪造请求.举例来讲,某个恶意的网站上有一个指向你的网站的链接,如果 某个用户已经登录到你的网站上了,那么当这个 ...

  9. javascript 数组 排除null, undefined, 和不存在的元素

    The most common way to loop through the elements of an array is with a for loop: var o = [1,2,3,4,5] ...

  10. [Java] Tcp/udp 简单通信

    本文转自  我自己的博客guozeyiblog.cn 欢迎来訪 效果图: //UDP通信 import java.awt.*; import java.awt.event.ActionEvent; i ...