• Java IO_002.InputStream与OutputStream--字节流对数据的操作(读取与写入)


    Java IO之FileInputStream与FileOutputStream对象常用操作

    涉及到文件(非文件夹)内容的操作,除了要用到File(见之前文章),另外就必须用到输入流输出流

    输入流:该流处理时,数据由外部流向程序(内存),一般指代“读取数据”,更清晰点地说:从外部读取数据到内存中。

    输出流:该流处理时,数据由程序(内存)流向外部,一般指代“写入数据”,更清晰点地说:将数据从内存写入到外部。

    如果要操作字节(比如Soket,字节数据、图片、视屏等非纯文本文件),则采用字节输入流字节输出流。在Java中,可使用: InputStream  与 OutputStream 及其子类。

    如果要操作字符(比如字符数据、纯文本文件),则采用字符输入流字符输出流。在Java中,可使用:Reader Writer 及其子类。

    对字节的操作,采用 InputStream与OutputStream。它们的为声明分别为:

    public abstract class InputStream implements Closeable 

    public abstract class OutputStream implements Closeable, Flushable 

    它们都是抽象类,需要由具体子类进行实例化。

    InputStream主要子类有:

    • AudioInputStream:读取音像媒体的字节流。
    • ByteArrayInputStream:读取字节数组的字节流。
    • FileInputStream:读取文件的字节流。
    • FilterInputStream:过滤器输入流,用于装饰。其子类有:PushbackInputStream , BufferedInputStream
    • ObjectInputStream:读取序列化的对象的字节流。
    • PipedInputStream:读取管道的字节流。
    • SequenceInputStream:读取序列的字节流。
    • PushbackInputStream:读取可以推回的字节流。继承自:FilterInputStream
    • BufferedInputStream:读取有缓存效果的字节流。继承自:FilterInputStream
    • StringBufferInputStream:读取字符缓冲的字节流。已过时,不作介绍。

     常用的有FileInputStream,我们将以它为例。

    OutputStream主要子类有:

    • ByteArrayOutputStream:将字节写入到字节数组
    • FileOutputStream:将字节写入到文件
    • FilterOutputStream:过滤器输出流,用于装饰
    • ObjectOutputStream:将字节写入到序列化对象
    • PipedOutputStream:将字节写入管道

     常用的有FileOutputStream,我们将以它为例。

    InputStream与OutputStream的方法

    InputStream字节输入流,其主要方法有:

    int available():获取可用的字节总长度。返回int类型,该方法只要用于获取可被后续线程使用的流的长度,并且随已读取字节的变化而变化(见下边例子),特别是用它来表示文件大小时并不可靠(因为特大文件的字节长度可能是long字节。对于文件字节数,可以使用file.length()来代替)。
    void close():释放流对象。用于关闭资源。close()后无法进行read及skip等操作。所以一般在流操作结束后进行close()调用。
    void mark(int readlimit):标记流的位置。系统不一定支持。不推荐使用。
    boolean markSupported():检测是否支持流位置标记。(mark方法与reset方法在其支持下才可用。一般能不用则不用此3个方法)
    abstract int read():从流中读取一个字节,如果没有数据,返回-1。
    int read(byte[] b):从流中读取字节,并将数据存入到指定的字节数组中,读取的字节数为指定数组的长度。如果没有数据,返回-1。
    int read(byte[] b, int off, int len):从流中读取字节,并将数据存入到指定的字节数组中,读取的字节数为len,存入时从数组off开始存。如果没有数据,返回-1。
    void reset():从新设置流的开始。系统不一定支持。不推荐使用。
    long skip(long n):跳过指定数目字节。可以是正数负数或0(对于文件流来说,该方法已被重载,可以用来解决系统不支持reset()问题。负数是往回转跳,0不进行转跳。)。

    输入字节流InputStream用于“读取”,其中最常用的方法是:read(),   read(byte[] b)read(byte[] b, int off, int len)

    综合测试代码:

     1 import java.io.File;
     2 import java.io.FileInputStream;
     3 import java.io.IOException;
     4 import java.io.InputStream;
     5 
     6 public class File001 {
     7     public static void main(String[] args) throws IOException {
     8         File file = new File("g:/java2019/file.txt");//文件内容:abc
     9         
    10         //打开流
    11         InputStream is = new FileInputStream(file);
    12         long len = file.length();
    13         System.out.println("available:"+is.available());
    14         System.out.println(is.read());//读取第一个字节:a
    15         System.out.println(is.read());//读取第一个字节:b
    16         System.out.println(is.read());//读取第一个字节:c
    17         System.out.println(is.read());//-1
    18         System.out.println(is.read());//-1
    19         System.out.println(is.read());//-1
    20         
    21         System.out.println("available:"+is.available());
    22         
    23         if(is.markSupported()){
    24             System.out.println("IO支持标记,可以进行重定位到开头标记处。");
    25             is.reset();
    26         }else{
    27             System.out.println("IO不支持标记,不可以进行重定位到开头标记处。使用回跳处理。");
    28             is.skip(-len);
    29         }
    30         
    31         for(int i=0;(i=is.read())!=-1;){
    32             System.out.println(i);
    33         }
    34         
    35         is.skip(-len);
    36         
    37         byte[] b3 = new byte[3];
    38         int len2 = is.read(b3,0,1);//从流中读取1个字节,存在b3字节数组中,从b3的0位置开始存。
    39         System.out.println("读取长度为::"+len2);
    40         System.out.println("first byte:"+b3[0]);
    41         
    42         is.skip(-1);
    43         is.read(b3);//从流中读取b3字节数组对应大小的字节存入b3中。
    44         for(byte b : b3){
    45             System.out.println(b);
    46         }
    47         
    48         //关闭流
    49         is.close();
    50     }
    51 
    52 }

    输出:

    available:3
    97
    98
    99
    -1
    -1
    -1
    available:0
    IO不支持标记,不可以进行重定位到开头标记处。使用回跳处理。
    97
    98
    99
    读取长度为::1
    first byte:97
    97
    98
    99

    说明:

    • FileInputStream是文件字节输入流。其构造方法有:FileInputStream(File file)  ,FileInputStream(String name), FileInputStream(FileDescriptor fdObj)。其中FileInputStream(String name)最为常用,它其实调用的也是FileInputStream(File file)。如果没有什么获取文件指定大小(需要用到File对象的length()方法:其实也可以通过name再构造一个File对象),推荐使用FileInputStream(String name),它最为简洁。
    • FileInputStream对象一旦进行实例化,就会立刻进行文件的打开,所以如果文件不存在,会抛出FileNotFoundException异常(属于IOException)。所以该流使用结束后必须调用close()方法来进行关闭,进行资源释放。
    • read()方法一次从文件输入流中读取一个字节,并返回int类型,并不返回byte类型,因为具体读取到的字节属于属于-128到127(占8位),直接返回的话,难以判定是读取到的字节数是-1,还是读取到结尾了,可能造成读取中断问题。所以返回int的话,会将8位的-1转化为32位int类型的255,避免冲突。read(byte[] b)以及read(byte[] b, int off, int len)方法一次读取数个字节,返回读取到的字节数,读取到结尾时返回-1。
    • read()方法是阻塞的。即线程运行到read()处,该线程必须等待read()完成才能进行该线程后续代码执行操作。在网络通信状态不稳定或者socket等待时,往往配合多线程进行处理。read(byte[] b)以及read(byte[] b, int off, int len)同理。
    • 对于文件流的读取,推荐使用read(byte[] b, int off, int len)来处理,可以减少读取次数,取得高效。
    • for(int i=0;(i=is.read())!=-1;){} 块可用于循环读取输入流的字节,当读取到的结尾时返回-1。也可以用int i=0;while((i=is.read())!=-1){}块,效果同样(只是多了一行)。

    OutputStream字节输入流,其主要方法有:

    void close():释放流对象。用于关闭资源。close()后无法进行write及flush等操作。所以一般在流操作结束后进行close()调用。
    void flush():刷新输出流,以便数据能够完全被写入。
    void write(byte[] b):一次写入所给的字节数组的所有数据。
    void write(byte[] b, int off, int len):一次写入所给的字节数组从off位置开始,长度为len的数据。
    abstract void write(int b):一次写入一个字节。

    输出字节流InputStream用于“写入”,其中最常用的方法是:write(byte[] b) , write(byte[] b, int off, int len)write(int b)

    测试代码:

     1 import java.io.FileOutputStream;
     2 import java.io.IOException;
     3 import java.io.OutputStream;
     4 
     5 public class File002 {
     6     public static void main(String[] args) throws IOException {
     7         String filepath = "G:/java2019/file123.txt";
     8         //打开文件构造输出流,如果文件不存在则进行创建,如果文件上级路径不存在,则抛出FileNotFoundException
     9         OutputStream os = new FileOutputStream(filepath);
    10 
    11         os.write(97);//写入a
    12         os.write(98);//写入b
    13         os.write('c');//写入c
    14         
    15         byte[] b = new byte[]{97,98,99};
    16         
    17         os.write(b);
    18         
    19         os.write(b, 2, 1);
    20         os.write(b, 1, 1);
    21         os.write(b, 0, 1);
    22         
    23         //关闭输出流
    24         os.close();
    25         
    26         //再次打开,需要再次构造。在文件内容后边进行写入。
    27         os = new FileOutputStream(filepath, true);
    28         String LINE = System.getProperty("line.separator");
    29         byte[] bLine = null;
    30         if(LINE.equals("
    ")){
    31             bLine = new byte[]{10}; 
    32         }else if(LINE.equals("
    ")){
    33             bLine = new byte[]{13};
    34         }else{//  LINE.equals("
    ")
    35             bLine = new byte[]{10,13};
    36         }
    37         
    38         //输出换行
    39         os.write(bLine);
    40         
    41         os.write(new byte[]{'A','B','C'});
    42         
    43         //关闭输出流
    44         os.close();
    45         
    46     }
    47 }

    文件内容:

    abcabccba

    (这时是空白行)
    ABC

    说明:

    • FileOutputStream是文件字节输出流。其构造方法有:FileOutputStream(File file)  ,FileOutputStream(File file, boolean append)  ,FileOutputStream(String name),FileOutputStream(String name, boolean append), FileOutputStream(FileDescriptor fdObj)。其中FileOutputStream(String name)及FileOutputStream(String name, boolean append)最为常用,它其实调用的也是FileOutputStream(File file)或FileOutputStream(File file, boolean append)。如果没有什么获取文件指定大小(需要用到File对象的length()方法:其实也可以通过name再构造一个File对象),推荐使用FileoutputStream(String name)及FileOutputStream(String name, boolean append),它最为简洁。boolean类型的参数append指明对文件内容的写入是否要接在文件末尾,如果不想覆盖原来文件的内容,则需要使用FileOutputStream(name,true),因为默认情况下是false(会覆盖)。
    • FileOutputStream对象一旦进行实例化,就会立刻进行文件的打开,所以如果文件不存在,会自动创建,如果文件所在路径(上级目录)不存在,会抛出FileNotFoundException异常(属于IOException)。所以该流使用结束后必须调用close()方法来进行关闭,进行资源释放。
    • write(int b)方法一次向文件输出流中写入一个字节,int类型会最终转化为byte类型。write(byte[] b)以及write(byte[] b, int off, int len)方法一次写入数个字节。
    • write()方法是不会阻塞的。wrie(byte[] b)以及write(byte[] b, int off, int len)同理。
    • 对于文件流的写入,推荐使用write(byte[] b, int off, int len)来处理,可以减少写入次数,取得高效。
    • byte[] b=new byte[1024*8];int len=0;while((len=is.read(b))!=-1){os.write(b,0,len);}块可以配合读取、写入操作,进行高效的文件的复制。

    高效的字节文件复制操作代码:

     1 import java.io.FileInputStream;
     2 import java.io.FileOutputStream;
     3 import java.io.IOException;
     4 import java.io.InputStream;
     5 import java.io.OutputStream;
     6 
     7 public class File003 {
     8     public static void main(String[] args) throws IOException {
     9         String from = "G:/java2019/file.txt";
    10         String to = "G:/java2019/file2.txt";
    11         InputStream is = new FileInputStream(from);
    12         OutputStream os = new FileOutputStream(to);
    13         
    14         byte[] b = new byte[1024*8];
    15         int len = 0;
    16         while((len=is.read(b))!=-1){
    17             os.write(b, 0, len);
    18         }
    19 
    20         is.close();
    21         os.close();
    22     }
    23 }

    IO中,要处理具体的异常,可以这样:

     1 import java.io.FileInputStream;
     2 import java.io.FileOutputStream;
     3 import java.io.IOException;
     4 import java.io.InputStream;
     5 import java.io.OutputStream;
     6 
     7 public class File004 {
     8     public static void main(String[] args) {
     9         String from = "G:/java2019/file.txt";
    10         String to = "G:/java2019/file2.txt";
    11         InputStream is = null;
    12         OutputStream os = null;
    13         try {
    14             is = new FileInputStream(from);
    15             os = new FileOutputStream(to);
    16 
    17             byte[] b = new byte[1024 * 8];
    18             int len = 0;
    19             while ((len = is.read(b)) != -1) {
    20                 os.write(b, 0, len);
    21             }
    22 
    23         } catch (IOException e) {
    24             e.printStackTrace();
    25         } finally {
    26             if (is != null) {
    27                 try {
    28                     is.close();
    29                 } catch (IOException e) {
    30                     e.printStackTrace();
    31                 }
    32             }
    33 
    34             if (os != null) {
    35                 try {
    36                     os.close();
    37                 } catch (IOException e) {
    38                     e.printStackTrace();
    39                 }
    40             }
    41         }
    42 
    43     }
    44 }

    不过这样很烦索,如果在JDK1.7及以上版本,可以使用try-resource改进,代码:

     1 import java.io.FileInputStream;
     2 import java.io.FileOutputStream;
     3 import java.io.IOException;
     4 import java.io.InputStream;
     5 import java.io.OutputStream;
     6 
     7 public class File005 {
     8     public static void main(String[] args) {
     9         String from = "G:/java2019/file.txt";
    10         String to = "G:/java2019/file2.txt";
    11         try (InputStream is = new FileInputStream(from);OutputStream os = new FileOutputStream(to);) {
    12             byte[] b = new byte[1024 * 8];
    13             int len = 0;
    14             while ((len = is.read(b)) != -1) {
    15                 os.write(b, 0, len);
    16             }
    17         } catch (IOException e) {
    18             e.printStackTrace();
    19         }
    20 
    21     }
    22 }

    JAVA也提供了比较高效的内置缓存流:BufferedInputStream及BufferedOutputStream。其内置缓冲区大小默认为1024*8(如果需要改变,可以在构造的时候传入其它值)。它们直接由InputSteam及OutputStream构造,所有方法都与InputStream及OutputStream相同。不过不同的是对于OutputStream,其write()实际上是写入到缓冲区,然后判断缓冲区是否满了,如果满了则使用flush()刷新缓冲区,同时写入文件,如果最后一次的时候刚才未满,则不能保证是否写入,这样会造成断尾了。可以使用其flush()方法,或者当进行close()的时候,也会进行缓冲区的刷新及文件的写入(不过对于JDK1.7及以上版本使用try-resource处理异常的情况下,会自动进行close(),不太需要担心)

    BufferedInputStream构造器:

    public BufferedInputStream(InputStream in):以字节输入流构造缓冲输入流,默认1024*8的缓冲区,常用。

    public BufferedInputStream(InputStream in, int size) :以字节输入流构造缓冲输入流,缓冲区大小由size指定。

    BufferedOutputStream构造器:

    public BufferedOutputStream(OutputStream out):以字节输出流构造缓冲输出流,默认1024*8的缓冲区,常用。

    public BufferedOutputStream(OutputStream out, int size):以字节输出流构造缓冲输出流,缓冲区大小由size指定。

    测试代码:

     1 import java.io.BufferedInputStream;
     2 import java.io.BufferedOutputStream;
     3 import java.io.FileInputStream;
     4 import java.io.FileOutputStream;
     5 import java.io.IOException;
     6 
     7 public class File006 {
     8     public static void main(String[] args) {
     9         String from = "G:/java2019/file.txt";
    10         String to = "G:/java2019/file2.txt";
    11         try (BufferedInputStream is = new BufferedInputStream(new FileInputStream(from));
    12                 BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(to));) {
    13             byte[] b = new byte[1024 * 8];
    14             int len = 0;
    15             while ((len = is.read(b)) != -1) {
    16                 os.write(b, 0, len);
    17             }
    18         } catch (IOException e) {
    19             e.printStackTrace();
    20         }
    21 
    22     }
    23 }

    说明:

    可以知道,使用字节缓冲流处理输入输出的时候,跟之前的代码相比,只需要改变构造器就可以,其它代码可以一概不变,因为缓冲字节流使用的是字节流对象构造并且直接重写其所有方法。

    要进行高效的字节流处理,一方面可以使用缓冲字节流,另一方面可以使用自己写的高效处理方法(同上边“字节文件的复制”)。推荐使用后者,更灵活,更高效。

    除了InputStream与OutputStream的应用中,除了FileInputStream与FileOutputStream常用来处理文件,也可以处理字节数组,数据,序列对象,管道,字符缓冲等。

    ByteArrayInputStream可以从字节数组中获取字节输入流数据,ByteArrayOutputStream可以将数据写入字节数组输出流。代码:

     1 import java.io.ByteArrayInputStream;
     2 import java.io.ByteArrayOutputStream;
     3 import java.io.IOException;
     4 import java.io.InputStream;
     5 import java.io.OutputStream;
     6 
     7 public class File007 {
     8     public static void main(String[] args) {
     9         byte[] b = new byte[] {97,98,99};
    10         try(InputStream is = new ByteArrayInputStream(b); OutputStream os = new ByteArrayOutputStream()){
    11             int i = 0;
    12             while((i=is.read())!=-1){
    13                 os.write(i);
    14             }
    15             
    16             System.out.println(os.toString());
    17         } catch (IOException e) {
    18             e.printStackTrace();
    19         }
    20         
    21     }
    22 }

    DataInputStream可以从int,long,float,double,char,byte[],boolean等中获取字节输入流的数据,DataOutputStream可以将int,long,float,double,char,byte[],boolean等数据写入字节输出流。代码:

     1 public class File007 {
     2     public static void main(String[] args) {
     3         byte[] b = new byte[] { 97, 98, 99, 100 };
     4         try (DataInputStream is = new DataInputStream(new ByteArrayInputStream(b));
     5                 DataOutputStream os = new DataOutputStream(new FileOutputStream("g:/java2019/file.txt"))) {
     6             char c = 0;
     7             c = is.readChar();// 读取两个字节
     8             os.writeChar(c);// 写入两个字节
     9             System.out.println(c);
    10             c = is.readChar();
    11             os.writeChar(c);
    12             System.out.println(c);
    13         } catch (IOException e) {
    14             e.printStackTrace();
    15         }
    16 
    17     }
    18 }

    输出:

    文件内容:abcd

    ObjectInputStream可以从已经序列化的对象(对象相对应的某种格式化的文件)等中获取字节输入流的数据,DataOutputStream可以将序列化的对象(实现Serialiazable接口的对象)写入字节输出流(最终变成相应格式文件数据)。代码:

    测试代码:

     1 import java.io.FileInputStream;
     2 import java.io.FileOutputStream;
     3 import java.io.IOException;
     4 import java.io.ObjectInputStream;
     5 import java.io.ObjectOutputStream;
     6 import java.io.Serializable;
     7 
     8 public class File008 {
     9     public static void main(String[] args) {
    10         try (ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("g:/java2019/file.txt"))) {
    11             User user = new User();
    12             user.setId(1);
    13             user.setName("dreamyoung");
    14             os.writeObject(user);
    15         } catch (IOException e) {
    16             e.printStackTrace();
    17         }
    18         
    19         try(ObjectInputStream is = new ObjectInputStream(new FileInputStream("g:/java2019/file.txt"))){
    20             try {
    21                 User user = (User)is.readObject();
    22                 System.out.println(user);
    23             } catch (ClassNotFoundException e) {
    24                 e.printStackTrace();
    25             }
    26         } catch (IOException e) {
    27             e.printStackTrace();
    28         }
    29 
    30     }
    31 }
    32 
    33 class User implements Serializable{
    34     private static final long serialVersionUID = 1L;
    35     private int id;
    36     private String name;
    37     public int getId() {
    38         return id;
    39     }
    40     public void setId(int id) {
    41         this.id = id;
    42     }
    43     public String getName() {
    44         return name;
    45     }
    46     public void setName(String name) {
    47         this.name = name;
    48     }
    49     
    50     @Override
    51     public String toString() {
    52         return "User [id=" + id + ", name=" + name + "]";
    53     }
    54 }

    输出:

    User [id=1, name=dreamyoung]

    文件内容:

    � sr User        I idL namet Ljava/lang/String;xp   t 

    dreamyoung

    说明:

    • 对象序列化通常指的是将对象数据(不是类)保存到文件,其格式由JVM自动生成。而反序列化指的是从文件中读取数据生成对象。
    • 要序列化的对象必须实现Serializable接口(通常还可以添加serialVersionUID),不然会出现 NotSerializableException 异常。

    SequenceInputStream可以从已经一个或多个的输入流中顺序获取字节输入流的数据。需要注意的是,没有SequenceOutputStream。代码:

     1 import java.io.FileInputStream;
     2 import java.io.FileOutputStream;
     3 import java.io.IOException;
     4 import java.io.SequenceInputStream;
     5 
     6 public class File009 {
     7     public static void main(String[] args) {
     8         //通过顺序流,将两个文件内容写入一个新文件
     9         try (FileInputStream fis1 = new FileInputStream("g:/java2019/file1.txt");//文件内容:111
    10                 FileInputStream fis2 = new FileInputStream("g:/java2019/file2.txt");//文件内容:222
    11                 SequenceInputStream is = new SequenceInputStream(fis1, fis2);
    12                 FileOutputStream fos = new FileOutputStream("g:/java2019/file3.txt")) {
    13             byte[] b = new byte[1024];
    14             int len = 0;
    15             while((len=is.read(b))!=-1){
    16                 fos.write(b,0,len);
    17             }
    18         } catch (IOException e) {
    19             e.printStackTrace();
    20         }
    21 
    22     }
    23 }

    文件file3.txt内容:111222

    要进行文件分割,必须配套PushbackInputStream类来使用,它可以使用 unread(int b)unread(byte[] b)  unread(byte[] b, int off, int len)将已经读取的内容返送回去,对于分割读取后超过的内容,则可以不读取。注意默认只能返回读一个字节,如果要推回的内容长度比较大,还是建议指定长度,否则会出现Push back buffer is full异常。分割文件的代码:

     1 import java.io.File;
     2 import java.io.FileInputStream;
     3 import java.io.FileOutputStream;
     4 import java.io.IOException;
     5 import java.io.PushbackInputStream;
     6 import java.util.Arrays;
     7 import java.util.Iterator;
     8 import java.util.List;
     9 
    10 public class File011 {
    11     public static void main(String[] args) {
    12         // 没有SequenceOutputStream,要分割文件,可以采用如下手段:
    13         File file1 = new File("g:/java2019/file1.txt");
    14         File file2 = new File("g:/java2019/file2.txt");
    15         File file3 = new File("g:/java2019/file3.txt");
    16 
    17         try (FileOutputStream fos1 = new FileOutputStream(file1);
    18                 FileOutputStream fos2 = new FileOutputStream(file2);
    19                 FileOutputStream fos3 = new FileOutputStream(file3);
    20                 PushbackInputStream fis = new PushbackInputStream(new FileInputStream("g:/java2019/file.txt"), 1024)) {
    21                 // file.txt内容:111111222222333333
    22             byte[] b = new byte[5];// 缓冲数组大小,不大于分割文件大小
    23             int splitSize = 6;// 分割文件大小
    24             int len = 0;
    25             List<FileOutputStream> list = Arrays.asList(fos1, fos2, fos3);
    26             Iterator<FileOutputStream> it = list.iterator();
    27             while (it.hasNext()) {
    28                 FileOutputStream fos = (FileOutputStream) it.next();
    29                 while (fos.getChannel().size() < splitSize && (len = fis.read(b)) != -1) {
    30                     int left = (int) fos.getChannel().size() + len - splitSize;
    31 
    32                     if (left > 0) {// 读取后会超出
    33                         for(int i=0;i<left;i++){
    34                             fis.unread(b[len-left+i]);
    35                         }
    36                         //fis.skip(-left);
    37                         fos.write(b, 0, len - left);
    38                     } else {
    39                         fos.write(b, 0, len);
    40                     }
    41                     
    42                     System.out.println(fos.toString() + ":" + fos.getChannel().size());
    43                 }
    44             }
    45 
    46         } catch (IOException e) {
    47             e.printStackTrace();
    48         }
    49 
    50     }

    输出:

    java.io.FileOutputStream@15db9742:5

    java.io.FileOutputStream@15db9742:6

    java.io.FileOutputStream@6d06d69c:5

    java.io.FileOutputStream@6d06d69c:6

    java.io.FileOutputStream@7852e922:5

    java.io.FileOutputStream@7852e922:6

    分割后各文件内容为:

    file1.txt: 111111

    file2.txt: 222222

    file3.txt: 333333

    PipedInputStream可以从管道中获取字节输入流数据,PipedOutputStream可以将数据写入管道输出流。将在网络编程的时候进行说明,本篇暂不介绍。

    总结:

    • FileInputStream与FileOutputStream可以以字节流形式处理文件,进行读取或写入操作。
    • 要进行高效的字节流处理,可以使用内置的BufferedInputStream及BufferedOutputStream缓冲字节流,它可以处理各种InputStream及OutputStream(不仅仅是FileInputStream及FileOutputStream)
    • 使用read(byte[] b, int off, int len)及write(byte[], int off, int len) 可以更高效的进行字节复制(可以替代缓冲字节流)

  • 相关阅读:
    JSON
    css3之自定义字体
    css3之2D转换
    JavaScript---认识JavaScipt
    学JS必看-JavaScript数据结构深度剖析
    Vue 过渡
    Vue 表单控件绑定
    Vue 方法与事件处理器
    Vue 列表渲染
    Vue 条件渲染
  • 原文地址:https://www.cnblogs.com/dreamyoung/p/11130063.html
Copyright © 2020-2023  润新知