标签:
一、概述
Java IO是Java用来读写数据(输入和输出)的API。这里主要介绍以下几点内容:
①,Java流式输入/输出 ②,Java流类的分类 ③,输入/输出流类 ④,常见的节点流和处理流 ⑤,文件流 ⑥,缓冲流 ⑦,数据流 ⑧,转换流 ⑨,Print流 ⑩,Object流
二、Java流式输入和输出
在Java程序中,对于数据的输入输出操作以"流"(Stream)方式进行;J2SDK提供了各种各样的"流"类,用以获取不同种类的数据;程序中通过标准的方法输入或输出数据。各类用途汇总如下:
三、Java流的分类
java.io包中定义了多个流类型(类或抽象类)来实现输入/输出功能。可以从不同的角度对其进行分类:
输入和输出:四个抽象类(凡是Stream结尾的否是字节流)
字节流 | 字符流 | |
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
节点流和处理流:
节点流为可以从一个特定的数据源(节点)读写数据(比如:文件,内存)
处理流是“连接”在已经存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能:
四、InputStream & OutputStream,Reader & Writer
①,InputStream
继承自InputStream的流都是用于向程序中输入数据,且数据的单位为字节(byte,8bits),下图中深色为节点流,浅色为处理流。
InputStream的基本方法:
//读取一个字节并以整数的形式返回(0~255) //如果返回-1表示已到输入流的末尾 int read() throws IOException //读取一系列字节并存储到一个数组buffer //返回实际读取的字节数,如果读取前已到输入流的末尾返回-1 int read(byte[] buffer) throws IOException //读取length个字节 //并存储到一个字节数组buffer,从length位置开始 //返回实际读取的字节数,如果读取前已到输入流的末尾返回-1 int read(byte[] buffer, int offset, int length) throws IOException //关闭流释放内存资源 void close() throws IOException //跳过n个字节不读,返回实际跳过的字节数 long skip(long n) throws IOException
②,OutputStream
继承自OutputStream的流是用于从程序中输出数据,切数据的单位是字节(byte,8bits),下图中深色为节点流,浅色为处理流。
OutputStream的基本方法:
//向输出流中写入一个字节数据,该字节数据位参数b的低8位 void write(int b) throws IOException //将一个字节类型的数组中的数据写入输出流 void writer(byte[] b) throws IOException //将一个字节类型的数组中的数据从指定位置(off)开始len个字节写入到输出流 void write(byte[] b, int off, int len) throws IOException //关闭流释放内存资源 void close() throws IOException //将输出流中缓冲的数据全部写出到目的地 void flush() throws IOException
③,Reader
继承自Reader的流都是用于向程序中输入数据,且数据的单位是字符(16bits,例如一个中文是两个字节表示);下图中深色为节点流,浅色为处理流:
Reader的基本方法
//读取一个字符并以整数的形式返回(0~255) //如果返回-1表示已到输入流的末尾 int read() throws IOException //读取一系列字符并存储到一个数组buffer //返回实际读取的字符数,如果读取前已到输入流的末尾返回-1表示已到输入流的末尾 int read(char[] cbuf) throws IOException //读取length个字符 //并存储到一个数组buffer,从length位置开始 //返回实际读取的字符数,如果读取前已到输入流的末尾返回-1表示已到输入流的末尾 int read(char[] cbuf, int offset, int length) throws IOException //关闭流释放内存资源 void close() throws IOException //跳过n个字符不读,返回实际跳过的字节数 long skip(long n) throws IOException
④,Writer
继承自Writer的流都是用于程序中输出数据,且数据的单位为字符(16bits);下图中深色为节点流,浅色为处理流:
Writer基本方法:
//向输出流中写入一个字符数据,该字符数据为参数c的低16位 void write(int c) throws IOException //将一个字符类型的数组中的数据写入输出流 void writer(char[] cbuf) throws IOException //将一个字符类型的数组中的数据从指定位置(offset)开始len个字节写入到输出流 void write(char[] cbuf, int offset, int len) throws IOException //将一个字符串中的字符写入到输出流 void write(String string) throws IOException //将一个字符串从offset开始的length个字符写入到输出流 void write(String string, int offset, int length) throws IOException //关闭流释放内存资源 void close() throws IOException //将输出流中缓冲的数据全部写出到目的地 void flush() throws IOException
五、常用的节点流和处理流
①,节点流类型
类型
字符流 | 字节流 | |
File(文件) |
FileReader FileWriter |
FileInputStream FileOutputStream |
Memory Array |
CharArrayReader CharArrayWriter |
ByteArrayInputStream ByteArrayOutputStream |
Memory String |
StringReader StringWriter |
--- |
Pipe(管道,线程) |
PipedReader PipedWriter |
PipedInputStream PipedOutputStream |
File(访问文件)
FileInputStream和FileOutputStream分别继承自OutputStream和OutputStream,用于向文件中输入和输出字节。
FileInputStream和FileOutputStream的构造方法:
FileInputStream: FileInputStream(File file) Creates a FileInputStream by opening a connection to an actual file, the file named by the File object file in the file system. FileInputStream(FileDescriptor fdObj) Creates a FileInputStream by using the file descriptor fdObj, which represents an existing connection to an actual file in the file system. FileInputStream(String name) Creates a FileInputStream by opening a connection to an actual file, the file named by the path name name in the file system. OutputStream: FileOutputStream(File file) Creates a file output stream to write to the file represented by the specified File object. FileOutputStream(File file, boolean append) Creates a file output stream to write to the file represented by the specified File object. FileOutputStream(FileDescriptor fdObj) Creates a file output stream to write to the specified file descriptor, which represents an existing connection to an actual file in the file system. FileOutputStream(String name) Creates a file output stream to write to the file with the specified name. FileOutputStream(String name, boolean append) Creates a file output stream to write to the file with the specified name.
FileInputStream和FileOutputStream类支持其父类InputStream和OutputStream所提供的数据读写方法。
注意:
在实例化FileInputStream和FileOutputStream时要用ty-catch语句加以处理,因为可能抛出FileNotFoundException。
在读写数据时也要用try-catch语句加以处理,因为可能抛出IOException。
例子:
1,FileInputStream & FileOutputStream
FileInputStream
public static void main(String[] args) { int b = 0; FileInputStream fis = null; try { fis = new FileInputStream("d:\\share\\java\\io\\TestFileInputStream.java"); } catch (FileNotFoundException e) { System.out.println("找不到指定文件"); System.exit(-1); } try { long num = 0; while((b = fis.read()) != -1) { System.out.print((char)b); num++; } fis.close(); System.out.println("共读取了" + num + "个字节"); } catch (IOException e) { System.out.println("文件读取错误"); System.exit(-1); } }
结果:对于中文乱码,因为是一个字节一个字节的读取,所以只读取了半个中文
控制台输出: import java.io.*; public class TestFileInputStream { public static void main(String[] args) { int b = 0; FileInputStream in = null; try { in = new FileInputStream("d:\\share\\java\\io\\TestFileInputStream.java"); } catch (FileNotFoundException e) { System.out.println("ÕÒ²»µ½Ö¸¶¨Îļþ"); System.exit(-1); } try { long num = 0; while((b=in.read())!=-1){ System.out.print((char)b); num++; } in.close(); System.out.println(); System.out.println("¹²¶ÁÈ¡ÁË "+num+" ¸ö×Ö½Ú"); } catch (IOException e1) { System.out.println("Îļþ¶ÁÈ¡´íÎó"); System.exit(-1); } } }共读取了700个字节
FileOutputStream:
public static void main(String[] args) { int b = 0; FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream("d:/share/java/HelloWorld.java"); fos = new FileOutputStream("d:/share/java/io/HW.java");//没有回自动新建一个文件 while ((b = fis.read()) != -1) { fos.write(b); } fis.close(); fos.close(); } catch (FileNotFoundException e) { System.out.println("找不到指定的文件"); System.exit(-1); } catch (IOException e) { System.out.println("文件复制错误"); System.exit(-1); } System.out.println("文件已复制"); }
输出:可以在d:/share/java/io中看到复制的文件HW.java
2,FileReader & FileWriter
FileReader:
public static void main(String[] args) { int c = 0; FileReader fr = null; try { fr = new FileReader("d:\\share\\java\\io\\TestFileReader.java"); while((c = fr.read()) != -1) { System.out.print((char)c); } fr.close(); } catch (FileNotFoundException e) { System.out.println("找不到指定文件"); } catch (IOException e) { System.out.println("读取文件出错"); } }
FileWriter:
例一:
public static void main(String[] args) { FileWriter fw = null; try { fw = new FileWriter(new File("d:\\unicode.dat")); for(int i = 0; i <= 50000; i++) {//char最大为65535 fw.write(i); } fw.close(); } catch (IOException e) { e.printStackTrace(); System.out.println("文件写入错误"); System.exit(-1); } }
结果:D盘中的unicode.dat文件中的内容。
例二:
public static void main(String[] args) throws Exception { FileReader fr = new FileReader("d:/java/io/TestFileWriter2.java"); FileWriter fw = new FileWriter("d:/java/io/TestFileWriter2.bak"); int b; while((b = fr.read()) != -1) { fw.write(b); } fr.close(); fw.close(); }
②,处理流
处理流需要套接在节点流和其他处理流之上使用
处理类型 | 字符流 | 字节流 |
Buffering |
BufferReader BufferWriter |
BufferedInputStream BufferedOutputStream |
Converting between bytes and character |
InputStreamReader OutputStreamWriter |
|
Object Serialization | --- |
ObjectInputStream ObjectOutputstream |
Data Conversion | --- |
DataInputStream DataOutputStream |
Counting | LineNumberReader | LineNumberInputStream |
Peeking ahead | PushbackReader |
PushbackInputStream |
Printing | PrintWriter | PrintStream |
1,缓冲流
缓冲流要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法。
J2SDK提供了四种缓冲流,其常用的构造方法:
BufferedReader BufferedReader(Reader in) Creates a buffering character-input stream that uses a default-sized input buffer. BufferedReader(Reader in, int sz) Creates a buffering character-input stream that uses an input buffer of the specified size. BufferedWriter BufferedWriter(Writer out) Creates a buffered character-output stream that uses a default-sized output buffer. BufferedWriter(Writer out, int sz) Creates a new buffered character-output stream that uses an output buffer of the given size. BufferedInputStream BufferedInputStream(InputStream in) Creates a BufferedInputStream and saves its argument, the input stream in, for later use. BufferedInputStream(InputStream in, int size) Creates a BufferedInputStream with the specified buffer size, and saves its argument, the input stream in, for later use. BufferedOutputStream BufferedOutputStream(OutputStream out) Creates a new buffered output stream to write data to the specified underlying output stream. BufferedOutputStream(OutputStream out, int size) Creates a new buffered output stream to write data to the specified underlying output stream with the specified buffer size.
缓冲输入流支持其父类的mark和reset方法
BufferedReader提供了readLine方法用于读取一行字符串(以\r或\n分隔)
BufferedWriter提供了newLine方法用于写入一个行分隔符
对于输出的缓冲流,写出的数据会先在内存中缓存,使用flush方法将会使内存中的数据立刻写出。
例一:
public static void main(String[] args) { try { FileInputStream fis = new FileInputStream("d:\\share\\java\\HelloWorld.java"); BufferedInputStream bis = new BufferedInputStream(fis); int c = 0; System.out.println(bis.read()); System.out.println(bis.read()); bis.mark(100); for(int i = 0; i <= 10 && (c=bis.read()) != -1; i++) { System.out.print((char)c + " "); } System.out.println(); bis.reset(); for(int i = 0; i <= 10 && (c=bis.read()) != -1; i++) { System.out.print((char)c + " "); } bis.close(); } catch (IOException e) { e.printStackTrace(); } }
输出:
47
42
a l ; s k j d f ;
a l ; s k j d f ;
例二:
public static void main(String[] args) { try { BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\dat2.txt")); BufferedReader br = new BufferedReader(new FileReader("d:\\dat2.txt")); String s = null; for(int i = 1; i<=100; i++) { s = String.valueOf(Math.random()); bw.write(s); bw.newLine(); } bw.flush(); while((s = br.readLine()) != null) {//读一行 System.out.println(s); } bw.close(); br.close(); } catch (IOException e) { e.printStackTrace(); } }
输出:
dat2.txt文件:
控制台输出:
2,转换流
转换流
InputStreamReader和OutputStreamWriter用于字节数据到字符数据之间的转换。
InputStreamReader需要和InputStream套接(把InputStream转换成InputStreamReader)
OutputStreamWriter需要和OutputStream套接(把OutputStreamWriter转换成OutputStream)
转换流在构造时可以指定其编码集合,例如:
InputStream is = new InputStreamReader(System.in, "IOS8859_1");
例一:
public static void main(String[] args) { try { OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d:\\bak\\char.txt")); osw.write("miscalkjsdlasjdlajslkdalksd"); System.out.println(osw.getEncoding()); osw.close(); osw = new OutputStreamWriter(new FileOutputStream("d:\\bak\\char.txt", true), "ISO8859_1");//true,追加 osw.write("sadasdasdasdasd"); System.out.println(osw.getEncoding()); osw.close(); } catch (Exception e) { e.printStackTrace(); } }
结果:
UTF8//系统默认的编码 ISO8859_1
例二:
public static void main(String[] args) { try { InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); String s = null; s = br.readLine(); while(s != null) { if("exit".equalsIgnoreCase(s)) break; System.out.println(s.toUpperCase()); s = br.readLine(); } br.close(); } catch (Exception e) { e.printStackTrace(); } }
输出:
add111
ADD111
exit
3,数据流
DataInputStream 和DataOutputStream分别继承自InputStream 和 OutputStream,它属于处理流,需要分别套接在InputStream 和 OutputStream类型的节点流上。
DataInputStream 和DataOutputStream提供了可以存取与机器无关的Java原始类型数据(如:int,double等)的方法。
DataInputStream 和DataOutputStream的构造方法:
DataInputStream(InputStream in) Creates a DataInputStream that uses the specified underlying InputStream. DataOutputStream(OutputStream out) Creates a new data output stream to write data to the specified underlying output stream.
ByteArrayInputStream 和 ByteArrayOutputStream
例子:
public static void main(String[] args) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream();//在内存中分配了一个字节数组 DataOutputStream dos = new DataOutputStream(baos); dos.writeDouble(Math.random()); dos.writeBoolean(true); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); System.out.println(bais.available()); DataInputStream dis = new DataInputStream(bais); System.out.println(dis.readDouble()); System.out.println(dis.readBoolean()); dos.close(); dis.close(); } catch (Exception e) { e.printStackTrace(); } }
结果:
9
0.5620896958440097
true
4,Print流
Print流(只有输出流没有输入流)
PrintWriter和PrintStream都属于输出流,分别针对于字符和字节
PrintWriter和PrintStream提供了重载的print方法
Println方法用于多种数据类型的输出
PrintWriter和PrintStream的输出操作不会抛出异常,用户通过检测错误状态获取错误信息
PrintWriter和PrintStream有自动flush方法
构造方法:
PrintWriter(File file) Creates a new PrintWriter, without automatic line flushing, with the specified file. PrintWriter(File file, String csn) Creates a new PrintWriter, without automatic line flushing, with the specified file and charset. PrintWriter(OutputStream out) Creates a new PrintWriter, without automatic line flushing, from an existing OutputStream. PrintWriter(OutputStream out, boolean autoFlush) Creates a new PrintWriter from an existing OutputStream. PrintWriter(String fileName) Creates a new PrintWriter, without automatic line flushing, with the specified file name. PrintWriter(String fileName, String csn) Creates a new PrintWriter, without automatic line flushing, with the specified file name and charset. PrintWriter(Writer out) Creates a new PrintWriter, without automatic line flushing. PrintWriter(Writer out, boolean autoFlush) Creates a new PrintWriter. PrintStream(File file) Creates a new print stream, without automatic line flushing, with the specified file. PrintStream(File file, String csn) Creates a new print stream, without automatic line flushing, with the specified file and charset. PrintStream(OutputStream out) Creates a new print stream. PrintStream(OutputStream out, boolean autoFlush) Creates a new print stream. PrintStream(OutputStream out, boolean autoFlush, String encoding) Creates a new print stream. PrintStream(String fileName) Creates a new print stream, without automatic line flushing, with the specified file name. PrintStream(String fileName, String csn) Creates a new print stream, without automatic line flushing, with the specified file name and charset.
例一:
public static void main(String[] args) { try { PrintStream ps = null; FileOutputStream fos = new FileOutputStream("d:\\bak\\log.dat"); ps = new PrintStream(fos); if(ps != null) { System.setOut(ps);//把ps设置成System.out.println();不再输出在控制台了 } int ln = 0; for(char c = 0; c <= 60000; c++) { System.out.print(c + ""); if( ln++ >= 100) { System.out.println(); ln = 0; } } } catch (Exception e) { e.printStackTrace(); } }
结果:d:\\bak\\log.dat,log.data文件
例二:
public static void main(String[] args) { try { PrintStream ps = System.out; BufferedReader br = new BufferedReader(new FileReader("d:\\bak\\log.dat")); String s = null; while((s = br.readLine()) != null) { ps.println(s); } br.close(); } catch (IOException e) { e.printStackTrace(); } }
结果:
例三:
public static void main(String[] args) { try { String s = null; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); FileWriter fw = new FileWriter("d:\\bak\\logfile.log", true);//日志 PrintWriter pw = new PrintWriter(fw); while ((s = br.readLine()) != null) { if("exit".equalsIgnoreCase(s)) break; System.out.println(s.toUpperCase()); pw.println("--------"); pw.println(s.toUpperCase()); pw.flush(); } pw.println("=====" + new Date() + "======"); pw.flush(); pw.close(); } catch (IOException e) { e.printStackTrace(); } }
结果:
控制台: 12121212121 adasdasdasdasd ADASDASDASDASD exit
文件:d:\\bak\\logfile.log,logfile.log文件
5,Object流
直接将Object写入或写出
transient关键字
serializable接口
externalizable接口
例一:
public class Test { public static void main(String[] args) { try { T t = new T(); t.k = 18; FileOutputStream fos = new FileOutputStream("d:/bak/testobjectio.dat"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(t); oos.flush(); oos.close(); FileInputStream fis = new FileInputStream("d:/bak/testobjectio.dat"); ObjectInputStream ois = new ObjectInputStream(fis); T t2 = (T) ois.readObject(); System.out.println(t2.i + "//" + t2.j + "//" + t2.d + "//" + t2.k); } catch (Exception e) { e.printStackTrace(); } } } class T implements Serializable { int i = 10; int j = 9; double d = 2.3; int k = 15; }
结果:
10//9//2.3//18
例二:
用transient修饰变量k
class T implements Serializable { int i = 10; int j = 9; double d = 2.3; transient int k = 15; }
结果:
10//9//2.3//0
transient修饰的变量k不会被写入进去,所以取出来的k为空,为默认值0
标签:
原文地址:http://www.cnblogs.com/lemon-now/p/5579922.html