精华内容
下载资源
问答
  • 例子:往一个文件内写东西以前的写法,总是在处理的最后都需要finally关闭资源,这样多了就会觉得很麻烦private static void oldtest(String filePath) throws FileNotFoundException {OutputStream out = new ...

    例子:往一个文件内写东西

    以前的写法,总是在流处理的最后都需要finally关闭资源,这样多了就会觉得很麻烦

    private static void oldtest(String filePath) throws FileNotFoundException {

    OutputStream out = new FileOutputStream(filePath);

    try {

    out.write((filePath+"我就是测试下用Java写点东西进来").getBytes());

    }catch (Exception e){

    e.printStackTrace();

    }finally {

    try {

    out.close();

    }catch (Exception e){

    e.printStackTrace();

    }

    }

    }

    Java7 里的try...catch...resource 写法可以流会自动回收,只需在try()括号里写流对象,这样就不用老是finally了

    //自动关闭资源写法

    private static void newtest(String filePath) throws FileNotFoundException {

    try(OutputStream out = new FileOutputStream(filePath);){

    out.write("用try...catch..resource写法试试会不会自动关闭资源".getBytes());

    }catch (Exception e){

    e.printStackTrace();

    }

    }

    我们可以看下源代码:

    e7f1a5c71d173103d086f67087cf9f3b.png

    这个outputStream实现了Closeable这个类,看下Closeable源代码

    f1b868c2adf70ddeb7caedd99f91eaa6.png

    看下AutoCloseable源代码:

    75192138f3e9e9e6864886ba0ee00342.png

    注意:

    1、使用该写法,需要该类有有实现AutoCloseable类

    2、实现了AutoCloseable接⼝的类,在try()⾥声明该类实例的时候,try结束后⾃动调⽤的 close⽅法,这个动作会早于finally⾥调⽤的⽅法

    3、不管是否出现异常,try()⾥的实例都会被调⽤close⽅法

    4、try⾥⾯可以声明多个⾃动关闭的对象,越早声明的对象,会越晚被close掉

    展开全文
  • java输入输出流

    2021-03-13 07:19:03
    java输入输出流java IO综述在整个Java.io包中最重要的就是5个类和一个接口。5个类指的是File、OutputStream、InputStream、Writer、Reader;一个接口指的是Serializable。Java I/O主要包括如下几个层次,包含三个...

    java输入输出流

    java IO综述

    在整个Java.io包中最重要的就是5个类和一个接口。5个类指的是File、OutputStream、InputStream、Writer、Reader;一个接口指的是Serializable。

    Java I/O主要包括如下几个层次,包含三个部分:

    1.流式部分――IO的主体部分;

    2.非流式部分――主要包含一些辅助流式部分的类,如:File类、RandomAccessFile类和FileDescriptor等类;

    3.其他类--文件读取部分的与安全相关的类,如:SerializablePermission类,以及与本地操作系统相关的文件系统的类,如:FileSystem类和Win32FileSystem类和WinNTFileSystem类。

    类的具体描述如下:

    1. File(文件特征与管理):用于文件或者目录的描述信息,例如生成新目录,修改文件名,删除文件,判断文件所在路径等。

    2. InputStream(二进制格式操作):抽象类,基于字节的输入操作,是所有输入流的父类。定义了所有输入流都具有的共同特征。

    3. OutputStream(二进制格式操作):抽象类。基于字节的输出操作。是所有输出流的父类。定义了所有输出流都具有的共同特征。

    Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此,JAVA中引入了处理字符的流。

    4. Reader(文件格式操作):抽象类,基于字符的输入操作。

    5. Writer(文件格式操作):抽象类,基于字符的输出操作。

    6. RandomAccessFile(随机文件操作):它的功能丰富,可以从文件的任意位置进行存取(输入输出)操作。

    Java中IO流的体系结构如图:

    dd2d5b4143aed7a3bf366aef115a2131.png

    非流式文件类--File类

    在Java语言的java.io包中,由File类提供了描述文件和目录的操作与管理方法。但File类不是InputStream、OutputStream或Reader、Writer的子类,因为它不负责数据的输入输出,而专门用来管理磁盘文件与目录。

    File类主要用于命名文件、查询文件属性和处理文件目录。

    File类共提供了三个不同的构造函数,以不同的参数形式灵活地接收文件和目录名信息。构造函数:

    1)File (String   pathname)

    例:File  f1=new File("FileTest1.txt"); //创建文件对象f1,f1所指的文件是在当前目录下创建的FileTest1.txt,注意此时实际文件并没有被创建。直到程序执行f1. createNewFile()时,才创建文件实体。

    2)File (String  parent , String child)

    例:File f2=new  File(“D:\\dir1","FileTest2.txt") ;//  注意:D:\\dir1目录事先必须存在,否则异常。在parent目录下创建文件对象。

    3)File (File parent , String child)

    例:File  f4=new File("\\dir3");

    File  f5=new File(f4,"FileTest5.txt");  //在如果 \\dir3目录不存在使用f4.mkdir()先创建

    一个对应于某磁盘文件或目录的File对象一经创建, 就可以通过调用它的方法来获得文件或目录的属性。

    常用方法:通过file对象.方法的形式调用

    369934bd6158ee3e9cd47597301b9ed7.png

    File类中还定义了一些对文件或目录进行管理、操作的方法,常用的方法有:

    1) public boolean renameTo( File newFile );重命名文件

    2) public void delete( );   删除文件

    3)  public boolean mkdir( ); 创建目录

    4)  public boolean createNewFile ( );创建文件实体

    说明:File类的方法:

    (1) exists()测试磁盘中指定的文件或目录是否存在

    (2) mkdir()创建文件对象指定的目录(单层目录)

    (3) createNewFile()创建文件对象指定的文件

    (4) list()返回目录中所有文件名字符串

    Java.IO流类库

    io流的四个基本类

    java.io包中包含了流式I/O所需要的所有类。在java.io包中有四个基本类:InputStream、OutputStream及Reader、Writer类,它们分别处理字节流和字符流:

    有时候我们需要将字节流转换成字符流,并且将字节流中读取到的字节按照指定字符集转换成字符并输入显示,或者将要写入的字符按照指定字符集转换成字节输出存储。这个时候就需要用到转换流。JavaSE API提供了两个转换流:InputStreamReader和OutputStreamWriter。前者用于字节输入流的转换,后者用于字节输出流的转换。

    dffdf9412f4522e77b190551dea9b100.png

    输入/输出字节流

    字符流

    输入流InputstreamReader

    输出流OutputStreamWriter

    8b60a31e1ae01b0751e2afe633eaf194.png

    io流的具体分类

    一、按I/O类型来总体分类:

    1. Memory   1)从/向内存数组读写数据: CharArrayReader、 CharArrayWriter,ByteArrayInputStream、ByteArrayOutputStream。2)从/向内存字符串读写数据 StringReader、StringWriter、StringBufferInputStream

    2.Pipe管道  实现管道的输入和输出(进程间通信): PipedReader、PipedWriter、PipedInputStream、PipedOutputStream

    3.File 文件流。对文件进行读、写操作 :FileReader、FileWriter、FileInputStream、FileOutputStream

    4. ObjectSerialization 对象输入、输出 :ObjectInputStream、ObjectOutputStream

    5.DataConversion数据流 按基本数据类型读、写(处理的数据是Java的基本类型(如布尔型,字节,整数和浮点数)):DataInputStream、DataOutputStream

    6.Printing 包含方便的打印方法 :PrintWriter、PrintStream

    7.Buffering缓冲  在读入或写出时,对数据进行缓存,以减少I/O的次数:BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream

    8.Filtering 滤流,在数据进行读或写时进行过滤:FilterReader、FilterWriter、FilterInputStream、FilterOutputStream过

    9.Concatenation合并输入 把多个输入流连接成一个输入流 :SequenceInputStream

    10.Counting计数  在读入数据时对行记数 :LineNumberReader、LineNumberInputStream

    11.Peeking Ahead 通过缓存机制,进行预读 :PushbackReader、PushbackInputStream

    12.Converting between Bytes and Characters 按照一定的编码/解码标准将字节流转换为字符流,或进行反向转换(Stream到Reader,Writer的转换类):InputStreamReader、OutputStreamWriter

    二、按数据来源(去向)分类:

    1、File(文件): FileInputStream, FileOutputStream, FileReader, FileWriter

    2、byte[]:ByteArrayInputStream, ByteArrayOutputStream

    3、Char[]: CharArrayReader, CharArrayWriter

    4、String: StringBufferInputStream, StringReader, StringWriter

    5、网络数据流:InputStream, OutputStream, Reader, Writer

    13c3e169eb5616ebaa3a793af99acb2b.png

    05584f59fcbc86a1c70136216fd97e23.png

    InputStream/OutputStream

    1.InputStream抽象类

    InputStream 为字节输入流,它本身为一个抽象类,必须依靠其子类实现各种功能,此抽象类是表示字节输入流的所有类的超类。 继承自InputStream  的流都是向程序中输入数据的,且数据单位为字节(8bit);

    InputStream是输入字节数据用的类,所以InputStream类提供了3种重载的read方法.Inputstream类中的常用方法:

    (1) public abstract int read( ):读取一个byte的数据,返回值是高位补0的int类型值。若返回值=-1说明没有读取到任何字节读取工作结束。

    (2) public int read(byte b[ ]):读取b.length个字节的数据放到b数组中。返回值是读取的字节数。该方法实际上是调用下一个方法实现的

    (3) public int read(byte b[ ], int off, int len):从输入流中最多读取len个字节的数据,存放到偏移量为off的b数组中。

    (4) public int available( ):返回输入流中可以读取的字节数。注意:若输入阻塞,当前线程将被挂起,如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用,

    (5) public long skip(long n):忽略输入流中的n个字节,返回值是实际忽略的字节数, 跳过一些字节来读取

    (6) public int close( ) :我们在使用完后,必须对我们打开的流进行关闭.

    主要的子类:

    1) FileInputStream把一个文件作为InputStream,实现对文件的读取操作

    2) ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用

    3) StringBufferInputStream:把一个String对象作为InputStream

    4) PipedInputStream:实现了pipe的概念,主要在线程中使用

    5) SequenceInputStream:把多个InputStream合并为一个InputStream

    2.OutputStream抽象类

    OutputStream提供了3个write方法来做数据的输出,这个是和InputStream是相对应的。

    1. public void write(byte b[ ]):将参数b中的字节写到输出流。

    2. public void write(byte b[ ], int off, int len) :将参数b的从偏移量off开始的len个字节写到输出流。

    3. public abstract void write(int b) :先将int转换为byte类型,把低字节写入到输出流中。

    4. public void flush( ) : 将数据缓冲区中数据全部输出,并清空缓冲区。

    5. public void close( ) : 关闭输出流并释放与流相关的系统资源。

    主要的子类:

    1) ByteArrayOutputStream:把信息存入内存中的一个缓冲区中

    2) FileOutputStream:把信息存入文件中

    3) PipedOutputStream:实现了pipe的概念,主要在线程中使用

    4) SequenceOutputStream:把多个OutStream合并为一个OutStream

    流结束的判断:方法read()的返回值为-1时;readLine()的返回值为null时。

    文件输入流: FileInputStream

    FileInputStream可以使用read()方法一次读入一个字节,并以int类型返回,或者是使用read()方法时读入至一个byte数组,byte数组的元素有多少个,就读入多少个字节。在将整个文件读取完成或写入完毕的过程中,这么一个byte数组通常被当作缓冲区,因为这么一个byte数组通常扮演承接数据的中间角色。

    作用:以文件作为数据输入源的数据流。或者说是打开文件,从文件读数据到内存的类。

    使用方法(1)

    File  fin=new File("d:/abc.txt");

    FileInputStream in=new FileInputStream( fin);

    使用方法(2)

    FileInputStream  in=new  FileInputStream(“d: /abc.txt”);

    文件输出流:FileOutputStream类

    作用:用来处理以文件作为数据输出目的数据流;或者说是从内存区读数据入文件FileOutputStream类用来处理以文件作为数据输出目的数据流;一个表示文件名的字符串,也可以是File或FileDescriptor对象。

    创建一个文件流对象有两种方法:

    方式1:

    File   f=new  File (“d:/myjava/write.txt ");

    FileOutputStream  out= new FileOutputStream (f);

    方式2:

    FileOutputStream out=new FileOutputStream(“d:/myjava/write.txt ");

    方式3:构造函数将 FileDescriptor()对象作为其参数。

    FileDescriptor() fd=new FileDescriptor();

    FileOutputStream f2=new FileOutputStream(fd);

    方式4:构造函数将文件名作为其第一参数,将布尔值作为第二参数。

    FileOutputStream f=new FileOutputStream("d:/abc.txt",true);

    注意: (1)文件中写数据时,若文件已经存在,则覆盖存在的文件;(2)的读/写操作结束时,应调用close方法关闭流。

    带缓存区的输入输出

    计算机访问外部设备非常耗时。访问外存的频率越高,造成CPU闲置的概率就越大。为了减少访问外存的次数,应该在一次对外设的访问中,读写更多的数据。为此,除了程序和流节点间交换数据必需的读写机制外,还应该增加缓冲机制。缓冲流就是每一个数据流分配一个缓冲区,一个缓冲区就是一个临时存储数据的内存。这样可以减少访问硬盘的次数,提高传输效率。

    BufferedInputStream:当向缓冲流写入数据时候,数据先写到缓冲区,待缓冲区写满后,系统一次性将数据发送给输出设备。

    BufferedOutputStream :当从向缓冲流读取数据时候,系统先从缓冲区读出数据,待缓冲区为空时,系统再从输入设备读取数据到缓冲区。

    1)将文件读入内存:

    将BufferedInputStream与FileInputStream相接

    FileInputStream in=new  FileInputStream( “file1.txt ” );

    BufferedInputStream bin=new  BufferedInputStream( in);

    2)将内存写入文件:

    将BufferedOutputStream与 FileOutputStream相接

    FileOutputStreamout=new FileOutputStream(“file1.txt”);

    BufferedOutputStream  bin=new BufferedInputStream(out);

    3)键盘输入流读到内存

    将BufferedReader与标准的数据流相接

    InputStreamReader sin=new InputStreamReader (System.in) ;

    BufferedReader bin=new  BufferedReader(sin);

    字符流Writer/Reader

    Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此,JAVA中引入了处理字符的流。

    1. Reader抽象类

    用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。

    1)FileReader :

    与FileInputStream对应,主要用来读取字符文件,使用缺省的字符编码,有三种构造函数:

    (1)将文件名作为字符串 :FileReader f=new FileReader(“c:/temp.txt”);

    (2)构造函数将File对象作为其参数。

    File f=new file(“c:/temp.txt”);

    FileReader f1=new FileReader(f);

    (3)  构造函数将FileDescriptor对象作为参数

    FileDescriptor() fd=new FileDescriptor()

    FileReader f2=new FileReader(fd);

    参数类型:

    1) 用指定字符数组作为参数:CharArrayReader(char[])

    2) 将字符数组作为输入流:CharArrayReader(char[], int, int)

    读取字符串,构造函数如下: public StringReader(String s);

    3) StringReader : 与StringBufferInputStream对应

    4) InputStreamReader  从输入流读取字节,在将它们转换成字符:Public inputstreamReader(inputstream is);

    5) FilterReader: 允许过滤字符流  protected filterReader(Reader r);

    6) BufferReader :接受Reader对象作为参数,并对其添加字符缓冲器,使用readline()方法可以读取一行。 Public BufferReader(Reader r);

    主要方法:

    (1)  public int read() throws IOException; //读取一个字符,返回值为读取的字符

    (2)  public int read(char cbuf[]) throws IOException; /*读取一系列字符到数组cbuf[]中,返回值为实际读取的字符的数量*/

    (3)  public abstract int read(char cbuf[],int off,int len) throws IOException; /*读取len个字符,从数组cbuf[]的下标off处开始存放,返回值为实际读取的字符数量,该方法必须由子类实现*/

    Writer抽象类

    写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。 其子类如下:

    1) FileWrite: 与FileOutputStream对应

    将字符类型数据写入文件,使用缺省字符编码和缓冲器大小。

    Public FileWrite(file f);

    2)  chararrayWrite:与ByteArrayOutputStream对应 ,将字符缓冲器用作输出。

    Public CharArrayWrite();

    3) PrintWrite:生成格式化输出

    public PrintWriter(outputstream os);

    4) filterWriter:用于写入过滤字符流

    protected FilterWriter(Writer w);

    5) PipedWriter:与PipedOutputStream对应

    6) StringWriter:无与之对应的以字节为导向的stream

    主要方法:

    (1)  public void write(int c) throws IOException; //将整型值c的低16位写入输出流

    (2)  public void write(char cbuf[]) throws IOException; //将字符数组cbuf[]写入输出流

    (3)  public abstract void write(char cbuf[],int off,int len) throws IOException; //将字符数组cbuf[]中的从索引为off的位置处开始的len个字符写入输出流

    (4)  public void write(String str) throws IOException; //将字符串str中的字符写入输出流

    (5)  public void write(String str,int off,int len) throws IOException; //将字符串str 中从索引off开始处的len个字符写入输出流

    (6)  flush( ) //刷空输出流,并输出所有被缓存的字节。

    (7)close()关闭流 public abstract void close() throws IOException

    InputStream与Reader差别 OutputStream与Writer差别

    InputStream和OutputStream类处理的是字节流,数据流中的最小单位是字节(8个bit)

    Reader与Writer处理的是字符流,在处理字符流时涉及了字符编码的转换问题

    Reader类能够将输入流中采用其他编码类型的字符转换为Unicode字符,然后在内存中为其分配内存

    Writer类能够将内存中的Unicode字符转换为其他编码类型的字符,再写到输出流中。

    FileWriter类(字符输出流类)

    构造方法:FileWriter fw = new FileWriter(String fileName);//创建字符输出流类对象和已存在的文件相关联。文件不存在的话,并创建。

    如: FileWriter fw = new FileWriter("C:\\1.txt");

    FileWriter fw = new FileWriter(String fileName,boolean append);//创建字符输出流类对象和已存在的文件相关联,并设置该该流对文件的操作是否为续写。

    如:FileWriter fw = new FileWriter("C:\\1.txt",ture); //表示在fw对文件再次写入时,会在该文件的结尾续写,并不会覆盖掉。

    主要方法:

    void write(String str)   //写入字符串。当执行完此方法后,字符数据还并没有写入到目的文件中去。此时字符数据会保存在缓冲区中。此时在使用刷新方法就可以使数据保存到目的文件中去。

    viod flush()//刷新该流中的缓冲。将缓冲区中的字符数据保存到目的文件中去。

    viod close()   //关闭此流。在关闭前会先刷新此流的缓冲区。在关闭后,再写入或者刷新的话,会抛IOException异常。

    如何选择IO流

    1)确定是数据源和数据目的(输入还是输出)

    源:输入流 InputStream Reader

    目的:输出流 OutputStream Writer

    2)明确操作的数据对象是否是纯文本

    是:字符流Reader,Writer

    否:字节流InputStream,OutputStream

    3)明确具体的设备。

    是硬盘文件:File++:

    读取:FileInputStream,, FileReader,

    写入:FileOutputStream,FileWriter

    是内存用数组

    byte[]:ByteArrayInputStream, ByteArrayOutputStream

    是char[]:CharArrayReader, CharArrayWriter

    是String:StringBufferInputStream(已过时,因为其只能用于String的每个字符都是8位的字符串), StringReader, StringWriter

    是网络用Socket流

    是键盘:用System.in(是一个InputStream对象)读取,用System.out(是一个OutoutStream对象)打印

    3)是否需要转换流

    是,就使用转换流,从Stream转化为Reader,Writer:InputStreamReader,OutputStreamWriter

    4)是否需要缓冲提高效率

    是就加上Buffered:BufferedInputStream, BufferedOuputStream, BuffereaReader, BufferedWriter

    5)是否需要格式化输出

    例:将一个文本文件中数据存储到另一个文件中。

    1)数据源和数据目的:读取流,InputStream Reader  输出:OutputStream Writer

    2)是否纯文本:是!这时就可以选择Reader Writer。

    3)设备:是硬盘文件。Reader体系中可以操作文件的对象是 FileReader FileWriter。

    FileReader fr = new FileReader("a.txt");

    FileWriter fw = new FileWriter("b.txt");

    4)是否需要提高效率:是,加Buffer

    BufferedReader bfr = new BufferedReader(new FileReader("a.txt"););

    BufferedWriter bfw = new BufferedWriter(new FileWriter("b.txt"););

    IOException异常类的子类

    1.public classEOFException :

    非正常到达文件尾或输入流尾时,抛出这种类型的异常。

    2.public class FileNotFoundException:

    当文件找不到时,抛出的异常。

    3.public class InterruptedIOException:

    当I/O操作被中断时,抛出这种类型的异常。

    数据流

    FileInputStream和FileOutputStream只能读写字节,如果我们要读写int、double或者字符串类型就要使用数据流进行包装。

    数据流用DataInputStream和DataOutputStream类,不能独立读写,必须对字节流进行包装后才能读写数据。数据流也是一种字节流。

    DataInputStream类构造方法

    DataInputStream(InputStream in)

    成员方法

    boolean readBoolean()//从输入流读取一个布尔值。

    byte readByte()//从输入流读取一个byte值。

    char readChar()//从输入流读取一个char值。

    double readDouble()//从输入流读取一个double值。

    float readFloat()//从输入流读取一个float值。

    int readInt()//从输入流中读取一个int值。

    String readUTF()//将输入流放回UTF字符串。

    5ccf8b1952102563fa0628fcce4aaf5b.png

    参考文献:

    http://blog.csdn.net/hguisu/article/details/7418161

    展开全文
  • Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:标准输入输出,文件的操作,网络上的数据,字符串流,对象,zip文件....本文的目的是为大家做一个简要的介绍。是一个很形象的概念,当程序...

    Java语言的输入输出功能是十分强大而灵活的,美中不足的是看上去输入输出的代码并不是很简洁,因为你往往需要包装许多不同的对象。在Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:标准输入输出,文件的操作,网络上的数据流,字符串流,对象流,zip文件流....本文的目的是为大家做一个简要的介绍。

    流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。这时候你就可以想象数据好像在这其中“流”动一样,如下图:

    42133.gif

    Java中的流分为两种,一种是字节流,另一种是字符流,分别由四个抽象类来表示(每种流包括输入和输出两种所以一共四个):InputStream,OutputStream,Reader,Writer。Java中其他多种多样变化的流均是由它们派生出来的:

    42134.gif

    42135.gif

    42136.gif

    42137.gif

    在这其中InputStream和OutputStream在早期的Java版本中就已经存在了,它们是基于字节流的,而基于字符流的Reader和Writer是后来加入作为补充的。以上的层次图是Java类库中的一个基本的层次体系。

    在这四个抽象类中,InputStream和Reader定义了完全相同的接口:

    int read()

    int read(char cbuf[])

    int read(char cbuf[], int offset, int length)

    而OutputStream和Writer也是如此:

    int write(int c)

    int write(char cbuf[])

    int write(char cbuf[], int offset, int length)

    这六个方法都是最基本的,read()和write()通过方法的重载来读写一个字节,或者一个字节数组。

    更多灵活多变的功能是由它们的子类来扩充完成的。知道了Java输入输出的基本层次结构以后,本文在这里想给大家一些以后可以反复应用例子,对于所有子类的细节及其功能并不详细讨论。

    import java.io.*;

    public class IOStreamDemo {

    public void samples() throws IOException {

    //1. 这是从键盘读入一行数据,返回的是一个字符串 BufferedReader stdin =new BufferedReader(new InputStreamReader(System.in));

    System.out.print("Enter a line:");

    System.out.println(stdin.readLine());

    //2. 这是从文件中逐行读入数据

    BufferedReader in = new BufferedReader(new FileReader("IOStreamDemo.java"));

    String s, s2 = new String();

    while((s = in.readLine())!= null)

    s2 += s + "\n";

    in.close();

    //3. 这是从一个字符串中逐个读入字节 StringReader in1 = new StringReader(s2);

    int c;

    while((c = in1.read()) != -1)

    System.out.print((char)c);

    //4. 这是将一个字符串写入文件 try {

    BufferedReader in2 = new BufferedReader(new StringReader(s2));

    PrintWriter out1 = new PrintWriter(new BufferedWriter(new FileWriter("IODemo.out")));

    int lineCount = 1;

    while((s = in2.readLine()) != null )

    out1.println(lineCount++ + ": " + s);

    out1.close();

    } catch(EOFException e) {

    System.err.println("End of stream");

    }

    }

    }

    对于上面的例子,需要说明的有以下几点:

    1.BufferedReader是Reader的一个子类,它具有缓冲的作用,避免了频繁的从物理设备中读取信息。它有以下两个构造函数:

    BufferedReader(Reader in)

    BufferedReader(Reader in, int sz)

    这里的sz是指定缓冲区的大小。

    它的基本方法:

    void close() //关闭流

    void mark(int readAheadLimit) //标记当前位置

    boolean markSupported() //是否支持标记

    int read() //继承自Reader的基本方法

    int read(char[] cbuf, int off, int len) //继承自Reader的基本方法

    String readLine() //读取一行内容并以字符串形式返回

    boolean ready() //判断流是否已经做好读入的准备

    void reset() //重设到最近的一个标记

    long skip(long n) //跳过指定个数的字符读取

    void close() //关闭流

    void mark(int readAheadLimit) //标记当前位置

    boolean markSupported() //是否支持标记

    int read() //继承自Reader的基本方法

    int read(char[] cbuf, int off, int len) //继承自Reader的基本方法

    String readLine() //读取一行内容并以字符串形式返回

    boolean ready() //判断流是否已经做好读入的准备

    void reset() //重设到最近的一个标记

    long skip(long n) //跳过指定个数的字符读取

    2. InputStreamReader是InputStream和Reader之间的桥梁,由于System.in是字节流,需要用它来包装之后变为字符流供给BufferedReader使用。

    3. PrintWriter out1 = new PrintWriter(new BufferedWriter(newFileWriter("IODemo.out")));

    这句话体现了Java输入输出系统的一个特点,为了达到某个目的,需要包装好几层。首先,输出目的地是文件IODemo.out,所以最内层包装的是FileWriter,建立一个输出文件流,接下来,我们希望这个流是缓冲的,所以用BufferedWriter来包装它以达到目的,最后,我们需要格式化输出结果,于是将PrintWriter包在最外层。

    Java提供了这样一个功能,将标准的输入输出流转向,也就是说,我们可以将某个其他的流设为标准输入或输出流,看下面这个例子:

    import java.io.*;

    public class Redirecting {

    public static void main(String[] args) throws IOException {

    PrintStream console = System.out;

    BufferedInputStream in = new BufferedInputStream( new FileInputStream( "Redirecting.java"));

    PrintStream out = new PrintStream( new BufferedOutputStream( new FileOutputStream("test.out")));

    System.setIn(in);

    System.setOut(out);

    BufferedReader br = new BufferedReader( new InputStreamReader(System.in));

    String s;

    while((s = br.readLine()) != null)

    System.out.println(s);

    out.close();

    System.setOut(console);

    }

    }

    在这里java.lang.System的静态方法:

    static void setIn(InputStream in)

    static void setOut(PrintStream out)

    提供了重新定义标准输入输出流的方法,这样做是很方便的,比如一个程序的结果有很多,有时候甚至要翻页显示,这样不便于观看结果,这是你就可以将标准输出流定义为一个文件流,程序运行完之后打开相应的文件观看结果,就直观了许多。

    Java流有着另一个重要的用途,那就是利用对象流对对象进行序列化。下面将开始介绍这方面的问题。

    在一个程序运行的时候,其中的变量数据是保存在内存中的,一旦程序结束这些数据将不会被保存,一种解决的办法是将数据写入文件,而Java中提供了一种机制,它可以将程序中的对象写入文件,之后再从文件中把对象读出来重新建立。这就是所谓的对象序列化Java中引入它主要是为了RMI(Remote Method Invocation)和Java Bean所用,不过在平时应用中,它也是很有用的一种技术。

    所有需要实现对象序列化的对象必须首先实现Serializable接口。下面看一个例子:

    import java.io.*;

    import java.util.*;

    public class Logon implements Serializable {

    private Date date = new Date();

    private String username;

    private transient String password;

    Logon(String name, String pwd) {

    username = name;

    password = pwd;

    }

    public String toString() {

    String pwd = (password == null) ? "(n/a)" : password;

    return "logon info: \n " + "username: " + username + "\n date: " + date + "\n password: " + pwd;

    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {

    Logon a = new Logon("Morgan", "morgan83");

    System.out.println( "logon a = " + a);

    ObjectOutputStream o = new ObjectOutputStream( new FileOutputStream("Logon.out"));

    o.writeObject(a);

    o.close();

    int seconds = 5;

    long t = System.currentTimeMillis() + seconds * 1000;

    while(System.currentTimeMillis() < t) ;

    ObjectInputStream in = new ObjectInputStream( new FileInputStream("Logon.out"));

    System.out.println( "Recovering object at " + new Date());

    a = (Logon)in.readObject();

    System.out.println("logon a = " + a);

    }

    }

    类Logon是一个记录登录信息的类,包括用户名和密码。首先它实现了接口Serializable,这就标志着它可以被序列化。之后再main方法里ObjectOutputStream o = newObjectOutputStream( new FileOutputStream("Logon.out"));新建一个对象输出流包装一个文件流,表示对象序列化的目的地是文件Logon.out。然后用方法writeObject开始写入。想要还原的时候也很简单ObjectInputStreamin = new ObjectInputStream( newFileInputStream("Logon.out"));新建一个对象输入流以文件流Logon.out为参数,之后调用readObject方法就可以了。

    需要说明一点,对象序列化有一个神奇之处就是,它建立了一张对象网,将当前要序列化的对象中所持有的引用指向的对象都包含起来一起写入到文件,更为奇妙的是,如果你一次序列化了好几个对象,它们中相同的内容将会被共享写入。这的确是一个非常好的机制。它可以用来实现深层拷贝。

    关键字transient在这里表示当前内容将不被序列化,比如例子中的密码,需要保密,所以没有被写入文件。

    对Java的输入输出功能,就浅浅的介绍到这里,本文的目的只是开一个好头,希望能让大家对Java输入输出流有个基本的认识。

    展开全文
  • Java输入输出流

    2021-03-08 23:27:43
    问题及答案来源自《Java程序员面试笔试宝典》第四章 Java基础知识 4.7输入输出流1、Java IO流的实现机制是什么?流可以分为两大类:字节流和字符流。字节流以字节为(8bt)单位,字符流以字符为(16bit)单位。字节流...

    问题及答案来源自《Java程序员面试笔试宝典》第四章 Java基础知识 4.7输入输出流

    1、Java IO流的实现机制是什么?

    流可以分为两大类:字节流和字符流。

    字节流以字节为(8bt)单位,字符流以字符为(16bit)单位。

    字节流包括两个抽象类:InputStream(输入流)和OutputStream(输出流)

    字符流包括两个抽象类:Reader(输入流)和Writer(输出流)

    字节流和字符流主要区别:

    字节流在处理输入输出时不会用到缓存,而字符流用到了缓存

    常见笔试题 - Java中有几种类型的流?

    常见的流有两种:字节流和字符流,字节流继承于InputStream(输入流)和OutputStream(输出流),字符流

    继承于Reader(输入流)和Writer(输出流),在java.io包中还有许多其他的流,流的主要作用是为了改善程序性能并且使用方便

    2、管理文件和目录的类是什么?

    Java中管理文件和文件夹的类是File类,File类常用方法:

    File(String pathname):根据指定路径创建File对象

    createNewFile():若目录或文件存在返回false,否则创建文件或文件夹

    delete():删除文件或文件夹

    isFile():判断这个对象表示的是否是文件

    isDirectory():判断这个对象表示的是否是文件夹

    listFiles():若对象表示目录,则返回目录中所有文件的File对象

    mkdir():根据当前对象指定的路径创建目录

    exists():判断对象对应的文件是否存在

    常见笔试题 - 如何列出某个目录下的所有目录和文件?

    详情见代码如下:

    1 importjava.io.File;2

    3 public classuseListFiles {4 public static voidmain(String[] args) {5 File file = new File("D:\\test");6 //判断目录是否存在

    7 if(!file.exists()){8 System.out.println("directory is empty!");9 return;10 }11 File[] fileList =file.listFiles();12 for(int i=0; i

    14 if(fileList[i].isDirectory()){15 System.out.println("directory is: " +fileList[i].getName());16 } else{17 System.out.println("file is: " +fileList[i].getName());18 }19 }20 }21 }

    3、Java Socket是什么?

    什么是Socket:

    网络上的两个程序通过一个双向的通信连接实现数据的交换,这个双向链路的一端称为一个Socket

    Socket也称为套接字,可以用来实现不同虚拟机或不同计算机之间的通信

    Java中的Socket:

    面向连接的Socket通信协议(TCP)

    面向无连接的Socket通信协议(UDP)

    任何一个Socket都是由IP地址和端口号唯一确定的

    基于TCP的通信过程:

    首先Server(服务器)Listen(监听)指定的某个端口(建议使用大于1024的端口)是否有连接请求;

    然后Client(客户端)向Server端发出连接请求(Connect);最后Server端向Client端返回Accept消息(接受)

    一个连接就建立起来了,会话立即产生,此时Server端和Client端都可以通过Send、Write等方法与对方通信

    socket生命周期三个阶段:

    打开Socket

    使用Socket收发数据

    关闭Socket

    在Java中,可以使用ServerSocket来作为服务器端,Socket作为客户端来实现网络通信

    常见笔试题 - 用Socket实现客户端和服务端的通信,要求客户发送数据后能返回相同的数据

    首先创建一个名为Server.java的服务器端程序:

    1 import java.io.*;2 import java.net.*;3

    4 public classServer {5 public static voidmain(String[] args) {6 BufferedReader br = null;7 PrintWriter pw = null;8 try{9 ServerSocket server = new ServerSocket(8888);10 Socket socket =server.accept();11 //获取输入流

    12 br = new BufferedReader(newInputStreamReader(socket.getInputStream()));13 //获取输出流

    14 pw = new PrintWriter(socket.getOutputStream(), true);15 String s = br.readLine(); //获取接收的数据

    16 pw.println(s); //发送相同的数据给服务端

    17 } catch(Exception e){18 e.printStackTrace();19 } finally{20 try{21 br.close();22 pw.close();23 } catch(Exception e){24 e.printStackTrace();25 }26 }27 }28 }

    然后创建一个名为Client.java的客户端程序:

    1 import java.io.*;2 import java.net.*;3

    4 public classClient {5

    6 public static voidmain(String[] args) {7 BufferedReader br = null;8 PrintWriter pw = null;9 try{10 Socket socket = new Socket("localhost", 8888);11 //获取输入流与输出流

    12 br = new BufferedReader(newInputStreamReader(socket.getInputStream()));13 pw = new PrintWriter(socket.getOutputStream(), true);14 //向服务器发送数据

    15 pw.println("Hello");16 String s = null;17 while(true){18 s =br.readLine();19 if(s!=null){20 break;21 }22 }23 System.out.println(s);24 } catch(Exception e) {25 e.printStackTrace();26 } finally{27 try{28 br.close();29 pw.close();30 } catch(Exception e){31 e.printStackTrace();32 }33 }34 }35 }

    最后启动服务器端程序,然后运行客户端程序,客户端会把从服务器转发过来的数据都打印出来

    4、Java NIO是什么?

    NIO与IO:

    NIO是指Nonblocking IO,指的是非阻塞IO

    阻塞是指暂停一个线程的执行以等待某个条件的发生,例如某资源就绪

    当处理多个连接时用到多线程时,阻塞会导致大量线程进行上下文切换,使得程序运行效率底下

    而NIO可以解决这个问题,NIO通过Selector、Channel和Buffer来实现非阻塞的IO操作

    NIO原理:

    NIO的实现主要采用了Reactor(反应器)模式,这个设计模式和Observer(观察者)模式类似,只不过

    Observer模式只能处理一个事件源,而Reactor设计模式可以处理多个事件源

    NIO与传统的Socket方式比,由于NIO采用了非阻塞的方式,在处理大量并发请求时使用NIO比使用

    Socket的效率高的多!

    5、什么是Java序列化?

    Java提供了两种对象持久化的方法:序列化和外部序列化

    (1)序列化

    序列化:把对象的状态写在流里进行网络传输,或者保存到文件、数据库等系统里,在必要的时候可以

    把流读取出来重新构造一个相同的对象

    实现序列化:

    所有实现序列化的类必须实现Serializable接口

    使用输出流(FileOutputStream)来构造一个ObjectOutputStream对象

    接着使用该对象的writeObject方法将obj对象写出(保存其状态)

    序列化的两个特点:

    一个类能被序列化,那么它的子类也能被序列化

    由于static代表类的成员,transient代表对象的临时数据,这两种类型的数据成员是不能被序列化的

    序列化实例:

    1 import java.io.*;2

    3 public class People implementsSerializable{4 publicString name;5 public intage;6

    7 publicPeople(){8 this.name = "xxx";9 this.age = 18;10 }11

    12 public static voidmain(String[] args) {13 People p = newPeople();14 ObjectOutputStream oos = null;15 ObjectInputStream ois = null;16 try{17 //序列化

    18 FileOutputStream fos = new FileOutputStream("people.out");19 oos = newObjectOutputStream(fos);20 oos.writeObject(p);21 oos.close();22 } catch(Exception e) {23 e.printStackTrace();24 }25 People p1;26 try{27 //反序列化

    28 FileInputStream fis = new FileInputStream("people.out");29 ois = newObjectInputStream(fis);30 p1 =(People)ois.readObject();31 System.out.println(p1.name + " - " +p1.age);32 } catch(Exception e) {33 e.printStackTrace();34 }35 }36 }

    (2)外部序列化

    Java语言还提供了另外一种方式来实现对象持久化,即外部序列化

    接口如下:

    1 public interface Externalizable extendsSerializable{2 voidreadExternal(ObjectInput in);3 voidwriteExternal(ObjectOutput out);4 }

    外部序列化和序列化的主要区别:

    序列化是内置的API,只要实现Serializable接口就可以使用,不需要编写具体代码就可以实现对象的序列化

    而外部序列化中的读写接口必须由开发人员完成,难度更大,但更灵活,可以选择只持久化部分成员

    引申 - 在用接口Serializable实现序列化时,类中的所有属性都会被序列化,那么怎么样才能只序列化部分属性?

    用transient来控制序列化的属性,被transient修饰的属性是临时的,不会被序列化

    实现Externalizable接口,开发人员根据实际需求实现readExternal和writeExternal方法来控制序列化的属性

    展开全文
  • Java缓冲输入输出流

    2021-03-10 08:12:07
    Java缓冲输入输出流缓冲字节流默认有8192字节的缓冲区package com.wkcto.chapter06.filterstream;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.FileInputStream;import ...
  • JAVA输入输出流实验报告单吉林大学应用技术学院实验(训)报告单(电子版)实验编号08实验班级540972实验名称输入输出流实验任务书编号08实验组别27实验组成员陈静报告人陈静指导教师罗凡实 验 报 告1 读取文本文件内容...
  • java输入输出流又是什么呢?下面的文章要给大家介绍的就是这个方面的内容,一起来了解一下吧。Java当中,所有的数据都是使用流读写的,流是一组有序的数据序列,将数据从一个地方带到另一个地方,根据数据流向的不同...
  • 一、理论:1、什么是输入输出?...2、流的分类按照流向:按照流向分为输入流和输出流按照数据内容:字节流(能处理字节的流对象)、字符流(能处理字符的流对象)。字符流的实质:字节流读取文字字节数据后,...
  • 第8章输入输出数据流 南京农业大学谢忠红 输入输出数据流 1 数据流的基本概念 2 java io包中的输入输出流的基类 3 基本输入输出流的子类 文件流 缓冲输入输出流 4 IOException异常类的子类 5 随机存取文件 6 输入...
  • Java 输入输出流

    2021-02-28 18:33:39
    1.什么是IOJava中I/O操作主要是指使用Java进行输入,输出操作.Java所有的I/O机制都是基于数据进行输入输出,这些数据表示了字符或者字节数据的流动序列。Java的I/O提供了读写数据的标准方法。任何Java中表示...
  • 浅谈java输入输出流

    2021-03-15 21:17:05
    1.BufferedReader是Reader的一个子类,它具有缓冲的作用,避免了频繁的从物理设备中读取信息。它有以下两个构造函数:...它的基本方法:voidclose() //关闭流voidmark(int readAheadLimit)//标记当前位置b...
  • Java所有的I/O机制都是基于数据进行输入输出,这些数据表示了字符或者字节数据的流动序列。任何Java中表示数据源的对象都会提供以数据的方式读写它的数据的方法。Java.io是大多数面向数据的输入/输出类的...
  • java中执行lunix命令的时候使用PrintWriter来输出命令,使用input.readLine()来获取命令执行结果的时候,需要先关闭OutputStreamWriter然后使用input.readLine()来获取执行结果。在这里提醒自己。 部分代码如下 ...
  • java语言的输入输出功能是十分强大而灵活的,美中不足的是看上去输入输出的代码并...本文的目的是为大家介绍JAVA输入输出流实例详解。流的层次结构定义:java将读取数据对象成为输入流,能向其写入的对象叫输出...
  • 学会Java输入输出流,看这一篇就够了,建议收藏!

    千次阅读 多人点赞 2021-10-13 20:42:30
    一起回顾一下java流的使用。
  • 按流的方向分为:输入流和输出流2.按流的数据单位不同分为:字节流和字符流3.按流的功能不同分为:节点流和处理流(节点流表示的是直接操作节点(例如文件,键盘)的流,例如FileInputStream.处理流(过滤流)表示的是对...
  • 1.什么是IOJava中I/O操作主要是指使用Java进行输入,输出操作.Java所有的I/O机制都是基于数据进行输入输出,这些数据表示了字符或者字节数据的流动序列。Java的I/O提供了读写数据的标准方法。任何Java中表示...
  • java中需要手动释放的资源bai常见的有以下两个:流相du关资zhi源流相关资源一般遵循:1)先开后关dao,先开的输入流,再开的输出流,通过读取输入流写入输出流中,那么应该先关输出流,再关输入流,但是一般关闭输入...
  • Java所有的I/O机制都是基于数据进行输入输出,这些数据表示了字符或者字节数据的流动序列。Java的I/O提供了读写数据的标准方法。任何Java中表示数据源的对象都会提供以数据的方式读写它的数据的方法。Java....
  • 供大家参考,具体内容如下前端通过form表单的enctype属性,将数据传递方式修改为二进制”“的形式,服务端(servlet)通过 getInputStream() 获取信息, 运用java I/O 的基础操作将写入到一个服务端临时创建的...
  • java--标准输入输出流

    2021-03-21 09:52:45
    //读取键盘录入的数据写到a.txt//方式一private static void method() throws IOException {//创建输入流对象InputStream is = System.in;...//创建输出流对象FileWriter fw = new FileWriter("a.txt");//读取数据...
  • 例子:import java.io.File;import java.io.IOException;public class TestFile {public static void main(String args[]) throws IOException {File dir = new File("\\root");File f1 = new File(dir, "fileOne....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 149,893
精华内容 59,957
关键字:

java关闭输入输出流

java 订阅