Java IO

1,概述java

Java IO是Java用来读写数据(输入和输出)的API。这里主要介绍如下几点内容:c++

Java流式输入/输出
Java流类的分类 输入
/输出流类 常见的节点流和处理流 文件流 缓冲流 数据流 转换流 Print流 Object流

2,Java流式输入和输出数组

在Java程序中,对于数据的输入输出操做以"流"(Stream)方式进行;J2SDK提供了各类各样的"流"类,用以获取不一样种类的数据;程序中经过标准的方法输入或输出数据。各种用途汇总以下:缓存

  • 文件访问
  • 网络访问
  • 内存缓存访问
  • 线程内部通讯(管道)
  • 缓冲
  • 过滤
  • 解析
  • 读写文本 (Readers / Writers)
  • 读写基本类型数据 (long, int etc.)
  • 读写对象

3,Java流的分类网络

java.io包中定义了多个流类型(类或抽象类)来实现输入/输出功能。能够从不一样的角度对其进行分类:app

  • 按数据流的方向不一样能够分为输入流和输出流;
  • 按处理数据单位不一样能够分为字节流和字符流(一个字节1 byte=8 bits,一个字符Unicode=2字节);
  • 按照功能不一样能够分为节点流和处理流;

输入和输出:四个抽象类(凡是Stream结尾的否是字节流)dom

  字节流 字符流
输入流 InputStream Reader
输出流 OutputStream Writer

 

 

 

节点流和处理流:编码

节点流为能够从一个特定的数据源(节点)读写数据(好比:文件,内存)spa

处理流是“链接”在已经存在的流(节点流或处理流)之上,经过对数据的处理为程序提供更为强大的读写功能:线程

4,InputStream & OutputStream,Reader & Writer

4.1,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

4.2,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

4.3,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

4.4,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

5,经常使用的节点流和处理流

5.1,节点流类型

  类型 字符流 字节流
File(文件)

FileReader

FileWriter

FileInputStream

FileOutputStream

Memory Array

CharArrayReader

CharArrayWriter

ByteArrayInputStream

ByteArrayOutputStream

Memory String

StringReader

StringWriter

---
Pipe(管道,线程)

PipedReader

PipedWriter

PipedInputStream

PipedOutputStream

 

 

 

 

 

 

 

 

 

 

 

 

5.1.1,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(); }

 5.2,处理流

处理流须要套接在节点流和其余处理流之上使用

处理类型 字符流 字节流
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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5.2.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文件:

控制台输出:

 5.2.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

5.2.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

5.2.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.2.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
相关文章
相关标签/搜索