【黑马程序员】javaIO学习和总结

来源:互联网 发布:xpspeak41软件下载 编辑:程序博客网 时间:2024/05/01 21:35

------- Windows Phone 7手机开发、.Net培训、期待与您交流! -------

     JAVA.IO

通过数据流、序列化和文件系统提供系统输入和输出。

数据流就是指所有的数据之间通信的通道。

java中有关流的操作使用java.io.*;

JAVA流分类

1.输入输出流

2.节点流和处理流

3.文件流

4.缓冲流

5.数据流

6.转换流

7.Print流

8.Object流



JAVA流的分类:

java.io包中定义了多个流类型(类或者抽象类)来实现输入/输出功能:可以从不同的角度来对其分类:

按数据流的方向不同可以分为输入流和输出流。

按处理数据单位不同可以分为字节流和字符流。

按照功能不同可以分为节点流和处理流。

一、

输入输出方法

System类管理标准输入输出流和错误流
System.out:
把输出送到缺省的显示(通常是显示器)
System.in
从标准输入获取输入(通常是键盘)
System.err
把错误信息送到缺省的显示
每当main方法被执行时,就自动生成上述三个对象
public class ReadHello{ public static void main(String args[])  {  char inchar;     System.out.println(“Enter a character:”);      try{ inChar=(char)System.in.read();              Syste.out.println(“ “+ inChar);      }catch(IOException e)       {  Sytem.out.println(“Error reading from user”);           }  }}
import java.io.*;class IOTest{  public statics void main(String args[])    {try {  byte bArray[]=new byte[128];        System.out.println(“Enter something:”);        System.in.read(bArray);        System.out.print(“You entered:”);        System.out.println(bArray);    }catch(IOException ioe)     {  System.out.println(ioe.toString());  }   }}

为什么输入的是字符,输出是乱码?
原因:System.out.println(bArray)输出的是数组的地址而不是字符
改进:将字符数组变换成字符串
原来是:System.out.println(bArray);
现在为:String s=new String(bArray,0);
            System.out.println(s);
System.in是属于BufferedInputStream类型
System.out是属于PrintStream类型
System.err也是属于PrintStream类型

二、输入输出流的基类
Java中每一种流的基本功能依赖于基本类InputStream和OutputStream
它们是抽象类,不能直接使用
属于InputStream类的方法有:
read():从流中读入数据
skip():跳过流中若干字节数
available():返回流中可用字节数
mark():在流中标记一个位置
reset():返回标记过得位置
markSupport():是否支持标记和复位操作
close():关闭流
方法read()提供了三种从流中读数据的方法.
int read():读一个整数
int read(byte b[]):读多个字节到数组中
int read(byte,int off,int len);
属于OutputStream类的方法有:
write(int b):将一个整数输出到流中
write(byte b[]):将数组中的数据输出到流中
write(byte b[], int off,int len):将数组b中从off指定的位置开始len长度的数据输出到流中
flush():将缓冲区中的数据强制送出
close():关闭流.
PrintStream类
println()不属于OutputStream类,它是PrintStream类的子类,能提供复杂的输出
PrintStream类的方法有:
write, flush, checkError,print, println,close.
其中println可以输出多种形式的数据.例如:
println(String s), println(char c)等


三、File I/O

文件对象的建立
File fp=new File(“tempfile.txt”);
对文件操作要定义文件流
FileInputStream类用来打开一个输入文件
FileOutputStream类用来打开一个输出文件

文件流的建立
FileInputStream in=new FileInputStream(fp);
FileOutputStream out=new
                                       FileOutputStream(fp);
例:文件拷贝(注意要捕获文件异常)
输入流的参数是用于输入的文件名
输出流的参数是用于输出的文件名
import java.io.*;  class filestream {  public static void main(String args[])    { try{      File inFile=new File("file1.txt");      File outFile=new File("file2.txt");      FileInputStream fis=new FileInputStream(inFile);      FileOutputStream fos=new  FileOutputStream(outFile);  int c;  while((c=fis.read())!=-1)  fos.write(c);      fis.close(); fos.close();}catch(FileNotFoundException e) {    System.out.println("FileStreamsTest: "+e);}catch(IOException e) {System.err.println("FileStreamsTest: "+e);}}}
增加缓冲区流,减少访问硬盘的次数,提高效率

缓冲区流:
BufferedInputStream和 BufferedOutputStream
将它们与文件流相接
FileInputStream in=new  
                              FileInputStream(“file1.txt”);
BufferedInputStream bin=
                   new BufferedInputStream(in,256)
int len; byte bArray[]=new byte[256];
len=bin.read(bArray);
len中得到是长度, bArray中得到的是数据
只有缓冲区满时,才会将数据送到输出流.
Java在输出数据流中,当对方尚未将数据取走时,程序就会被阻塞.
有时要人为地将尚未填满的缓冲区中的数据送出,使用flush()方法.

6.4数据输入输出流

什么时候需要数据输入输出流?
文件流和缓冲区流的处理对象是字节或字节数组,利用数据输入输出流可以实现对文件的不同数据类型的读写.
DataInputStream、DataOutputStream
一种较为高级的数据输入输出方式,除了字节和字节数组,还可以处理int,float,boolean等类型.
还可以用readLine方法读取一行信息
可使用的方法:
write,writeBoolean…,read,readByte…等
数据流的建立
FileOutputStream fos=
             new  FileOutputStream(”file2.txt"));
DataInputStream dis=
                             new DataInputStream(fos)

数据输出流可以是一个已经建立好的输入数据流对象,例如网络的连结,文件等.
下面的例子显示如何利用数据输入输出流往文件中写不同类型的数据
class datainput_output{ public static void main(String args[]) throws  IOException  { FileOutputStream fos=new FileOutputStream(“a.txt”);     DataOutputStream dos=new DataOutputStream (fos);     try{ dos.writeBoolean(true);  dos.writeByte((byte)123);  dos.writeChar('J');  dos.writeDouble(3.141592654);  dos.writeFloat(2.7182f);  dos.writeInt(1234567890);  dos.writeLong(998877665544332211L);  dos.writeShort((short)11223);  }finally{  dos.close(); }DataInputStream dis=new DataInputStream(                        new FileInputStream("a.txt"));try{ System.out.println("\t "+dis.readBoolean());    System.out.println("\t "+dis.readByte());    System.out.println("\t "+dis.readChar());    System.out.println("\t "+dis.readDouble());    System.out.println("\t "+dis.readFloat());    System.out.println("\t "+dis.readInt());    System.out.println("\t "+dis.readLong());    System.out.println("\t "+dis.readShort());}finally{dis.close();}}}DateLine(InputStream in)(计算字符和行数){ DataInputStream data=new                                              DataInputStream(in);   String currentLine;   int lineCount=0; int charCount=0;   while((currentLine=dataIn.readLine())!=null)   {  ++lineCount;      charCount+=currentLine.length();   }   return (charCount/(float)lineCount);}



6.5随机存取文件

类RandomAccessFile
zip文件需要用随机方法处理
文件目录给出个文件的入口,可以随机读取.
创建一个随机文件
new RandomAccessFile(“file1.txt”, “r”);
new RandomAccessFile(“file2.txt”, “rw”);
随机文件可以同时完成读和写操作.
支持随机文件操作的方法:
readXXX()或writeXXX()
skipBytes();将指针乡下移动若干字节
seek():将指针调到所需位置
getFilePointer():返回指针当前位置
length():返回文件长度
利用seek(long pos)方法查找随机文件中的信息
例:把若干个32位的整数写到一个名为“temp.dat”的文件中,然后利用seek方法,以相反的顺序再读取这些数据
public class random_file{  public static void main(String args[])   { int data_arr[]={12,31,56,23,27,1,43,65,4,99};      try { RandomAccessFile randf=new                                       RandomAccessFile(“temp.dat”);        for (int i=0;i>data_arr.length;i++)            randf.writeInt(data_arr[i]);        for(int i=data_arr.length-1;i>=0;i--)        {    randf.seek(i*4);             System.out.println(randf.readInt());   }        randf.close();     }catch (IOException e)     {   System.out.println(“File access error: “+e);}  } }


6.6文件的其他操作

使用文件类获取文件的路径信息
设f是一个文件对象
File f=new File(“data”,temp.dat”);
f.getName():返回文件名   temp.dat
f.getParent():返回文件所在目录名   data
f.getPath():返回文件路径  data\temp.dat
f.getAbsolutePath():返回绝对路                         c:\myprog\data\temp.dat
例: 获取当前目录下所有文件名和文件的尺寸: 
import java.io.*;public class file_size{ public static void main(String args[])  { File files=new File(“.”);    String file_list[]=files.list();    for(int i=0;i<file_list.length;i++)    { File current_file=new File(file_list[i]);      System.out.println(file_list[i]+                     current_file.length());    }  }


6.7java中的unicode

在java中用unicode 表示字符和字符串
DatainputStream的readLine方法,  以字节形式读入, 以unicode形式输出
DataInputStream不适合输入是unicode的形式
处理字符用InputStreamReader 类和BufferedReader 类(jdk1.1)
import  java.io;//
(从键盘上读一个字符串)
public class CharInput{  public static void main(String args[])    {String s;                           throws IOException          InputStreamReader ir;        BufferedReader in;        ir=new InputStreamReader(System.in);        in=new BufferedReader(ir);        String s=in.readLine();        int i=Integer.parseInt(s); i=i*2;        System.out.println(“the result is” +i);     }}
问题:
如果字符流不是来自本地,有可能编码不一样,直接读取会读出不正确字符
处理方法:
ir=new InputStreamReader(is,”8859_1”);
采用的是iso8859_1编码方式,在不同平台之间正确转换字符.

import java.io.*;class filetounicode{  public static void main(String args[])   { try{ FileInputStream fis=new                                          FileInputStream("toyamei.txt");             InputStreamReader dis=new                                       InputStreamReader(fis);             BufferedReader reader=new                 String s;                      BufferedReader(dis);              while((s=reader.readLine())!=null)                {  System.out.println("read: "+s);}            dis.close();          }catch(IOException e) { }   }}




6.8 使用管道流
PipedInputStream和PipedOutputStream
创建管道流:
PipedInputStream pis=new  PipedInputStream();
PipedOutputStream pos=new PipedOutputStream(pis);
或:
PipedOutputStream pos=new PipedOutputStream();
PipedInputStream pis=new PipedInputStream(pos);
管道流一定是输入输出并用
例:将数据从输出管道进,从输入管道出
import java.io.*;                                                                            
class pipedstream
{  public static void main(String args[]) throws
                                                 IOException
{  byte aByteData1=123, aByteData2=111;
   PipedInputStream pis=
                      new PipedInputStream();
   PipedOutputStream pos=
                      new  PipedOutputStream(pis);
   System.out.println("PipedInputStream");
try{
    pos.write(aByteData);
 pos.write(aByteData2);
 System.out.println((byte)pis.read());
 System.out.println((byte)pis.read());
} finally {
     pis.close();
     pos.close();
}




6.9对象流
在java.io包中什么是对象的持续性?
能够纪录自己的状态一边将来再生的能力,叫对象的持续性
什么是串行化?
对象通过写出描述自己状态的的数值来记录自己的过程叫串行化.
什么是对象流?
能够输入输出对象的流.
两者什么关系?
将串行化的对象通过对象输入输出流写入文件或传送到其它地方.
一个相关的例子:从一个源读入一个简单的对象
import java.net;import java.io
public class GetString
{ public String getStringFromUrl(URL inURL)
   { InputStream in;
      try { in =inURL.openStream();
      }catch(IOException ioe)
      {System.out.printlin(“URL error;”+ioe);
        return null; }
      return getString(in);
   }通过url得到一个字符串
public String getStringFromSocket(Socket inSocket){  inputStream in;   try{ in=inSocket.getInputStreamSream();   }catch(IOEception ioe)   { System.out.println(“Socket error:”+ioe);      return null; }   return getString(in);} 通过socket得到一个字符串
public String getString(inputStream inStream){  String readString = new String();   DataInputStream in =new                                    DataInputSream(inStream);   char inChar;   try{ while(true)          { inChar=in.readByte();             readString=readString+inChar; }    }catch(EOFException eof)    {  System.out.println(readString);}    }catch(IOException ioe) {     { System.out.println(“error:”+ieo);}    return readString; }

下面的对象能读吗?Class testObject{ int x;   int y;   float angle;   String name;   public testObject(int x,int y,float angle,                                                   String name);   { this.x=x;this.y;this.angle;this.name=name;} }这仍然是一个简单的对象

对象流是怎样工作的?
允许可串行化的对象在流中传输
1.只有实现serializable接口的类才能被串行化
public class Student implements Serializable
{ int id;String name; int age;
   String department;
   public Student(int id, String name,int age,
                                        String department)
   { this.id=id;  this.name=name;
      this.age=age;  this.department =departmernt;
   }
}
2. 构造对象的输入输出流(将对象保存到文件中,或者通过网络传送到其他地方)
相应的类:ObjectInput
对象的输出: ObjectOutputStream
相应的方法:writeObject()
对象的输入:ObjectInputStream
相应的方法:readObject()
注:jdk1.1以上版本支持对象流操作
对象流举例:将Student类的一个实例写到文件中
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class Objectser
{public static void main(String args[]) 
 Student stu=new Student(981036,“Li Ming”,16,“CSD”);
{try {FileOutputStream fo=new
                    FileOutputStream(“date.ser”);
      ObjectOutputStream so=new                          
                    ObjectOutputStream(fo);
      os.writeObject(stu);so.close();
   }catch(Exception e) {;}
  }
import java.io.FileInputStream;import java.io.ObjectInputStream;public class ObjectRecov{ public static void main(String args[])   { Student stu;    try {FileInputStream fi=new                FileInputStream(“date.ser”);          ObjectInputStream si=new                ObjectInputStream(fi);     stu=(Student)si.readObject();si.close();    }catch(Exception e) {System.out.println(e);}    System.out.println(“ID: ”+stu.id+“name:”+    stu.name+“age:”+age+“dept.:”+stu.department);  }}




------- Windows Phone 7手机开发、.Net培训、期待与您交流! -------

原创粉丝点击