首页 > 技术文章 > java IO流 之 字节流

jalja 2016-11-04 13:47 原文

一、file类的常用操作

 

        File file=new File("E:\\test\\javaIo");
        
        System.out.println(file.isDirectory());//判断该文件是否是目录(如果该文件不存在也返回false)
        System.out.println(file.isFile());//判断文件是否是具体的文件
        System.out.println(file.exists());//判断文件是否存在
        System.out.println(file.mkdir());//创建目录  返回boolean类型
        System.out.println(file.delete());//删除文件或目录 返回boolean类型
        System.out.println(file.mkdirs());//创建多级目录  返回boolean类型
        
        File fileF=new File("E:\\test\\javaIo","1.txt");
        fileF.createNewFile();//创建文件
        fileF.delete();//删除文件
        
        System.out.println(file.getAbsolutePath());//获取文件的绝对路径   E:\test\javaIo
        System.out.println(file.getName());//获取文件名字     javaIo
        System.out.println(file.getParent());//获取父文件路径   E:\test
        System.out.println(file.getParentFile());//获取父文件对象

 

/**
     * 列出 指定目录下(包括子目录)的所有文件
     * @param file
     */
    public static void directoryList(File dir){
        if(!dir.exists()){
            throw new IllegalArgumentException("目录"+dir+"不存在");
        }
        if(!dir.isDirectory()){
            throw new IllegalArgumentException(dir+"不是目录");
        }
        //String[] file=dir.list(); //获取该目录下所有目录和文件的名字  (返回字符串数组)  
        File [] files=dir.listFiles();// 获取 该目录下所有目录和文件 的file对象
        if(files!=null && files.length>0){
            for (File file : files) {
                if(file.isDirectory()){
                    //如果是目录就做递归操作
                    directoryList(file);
                }else{
                    System.out.println(file.getName());
                }
            }
        }
    }

 

二、字节流与字符流

   字节流:字节流处理单元为1个字节,操作字节和字节数组,主要处理二进制数据所以字节流可用于处理任何类型的对象。字节流操作的是文件本身(当我们对文件进行读写操作时如果不调用close() 或 flush()方法时能看到数据的变化)。字节流主要是操作byte类型数据,以byte数组为准,主要操作类就是OutputStream、InputStream。

      按照流的作用或者流向分又可分为读写流(输入输出流):读(输入)流 InputStream;写(输出流) OutputStream。

     输入(读):将磁盘(文件)中的数据读入内存中。

     输出(写):将内存中的数据写入磁盘(文件)中。

      字符流:字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串。字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的。字符流操作的是缓冲区(当我们对文件进行读写操作时如果不调用close() 或 flush()方法时不能看到数据的变化)。

    注意: 所有文件的储存是都是字节(byte)的储存,在磁盘上保留的并不是文件的字符而是先把字符编码成字节,再储存这些字节到磁盘。在读取文件(特别是文本文件)时,也是一个字节一个字节地读取以形成字节序列。

三、字节输入流(InputStream)

输入:将磁盘中的数据读入内存中

InputStream 抽象类是表示字节输入流的所有类的超类。需要定义 InputStream 的子类的应用程序必须始终提供返回下一个输入字节的方法。

public abstract class InputStream implements Closeable {
    private static final int MAX_SKIP_BUFFER_SIZE = 2048;//最大缓冲区大小
  //读取一个字节的数据,并且返回读到得数据,如果返回-1,则表示读到输入流的末尾
    public abstract int read() throws IOException;
  //从输入流中读取一定量的字节,并将其存储在字节数组b中,返回实际读取的字节数,如果返回-1,则表示读到输入流的末尾
    public int read(byte b[]) throws IOException {
        return read(b, 0, b.length);
    }
   //将数据读入一个字节数组,同时返回读取的实际字节数,如果返回-1,则表示读到输入流的末尾。off指定在数组b中存放数据的起始偏移位置,len指定读取的最大字节数
    public int read(byte b[], int off, int len) throws IOException {
       
    }
  //跳过和放弃此输入流中的 n 个数据字节。 
    public long skip(long n) throws IOException {
    
    }
  //返回此输入流下一个方法调用可以不受阻塞地从此输入流读取或跳过的估计字节数。
    public int available() throws IOException {
        return 0;
    }
  //关闭此输入流并释放与该流关联的所有系统资源。 
    public void close() throws IOException {}
   //在此输入流中标记当前的位置。 
    public synchronized void mark(int readlimit) {}
   //将此流重新定位到对此输入流最后调用 mark 方法时的位置。
    public synchronized void reset() throws IOException {
        throw new IOException("mark/reset not supported");
    }
  //测试此输入流是否支持 mark 和 reset 方法。 
    public boolean markSupported() {
        return false;
    }
}

 FileInputStream  读取文件内容:

 1 public class InputStreamTest {
 2     public static void main(String[] args) throws IOException {
 3         readOne();
 4         readByte();
 5     }
 6     //public abstract int read() throws IOException
 7     //从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。
 8     //在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。 
 9     public static void readOne() throws IOException{
10         InputStream is=new FileInputStream("E:\\javaTest\\1.txt");
11         int by=0;
12         while((by=is.read())!=-1){
13             System.out.println((char)by);//转为char类型
14         }
15         is.close();
16     }
17     //public int read(byte[] b)throws IOException
18     //从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。以整数形式返回实际读取的字节数。
19     //在输入数据可用、检测到文件末尾或者抛出异常前,此方法一直阻塞。
20     public static void readByte() throws IOException{
21         InputStream is=new FileInputStream("E:\\javaTest\\1.txt");
22         byte []bytes=new byte[1024];
23         int len=0;
24         while((len=is.read(bytes))!=-1){
25             System.out.println(new String(bytes,0,len));
26         }
27         is.close();
28     }
29 }
View Code

 BufferedInputStream 字节输入(读)缓冲流

  字节流一字读写一个数组的速度明显比一次读写一个字节的速度快,这是因为加入了数组缓冲的效果,java设计的本身也考虑到了这种情况(装饰设计模式)所以提供了字节缓冲流(BufferedInputStream)。该流仅提供缓冲区,是为提高读写效率而设计的。真正操作文件还是需要基本流对象来实现。BufferedInputStream 是 InputStream 的子类具有一切父类的方法。

1     public static void bufferedInputStreamTest() throws IOException{
2         BufferedInputStream bis=new BufferedInputStream(new FileInputStream("E:\\javaTest\\5.txt"));
3         byte [] bytes=new byte[1024];
4         int len=0;
5         while((len=bis.read(bytes))!=-1){
6             System.out.println(new String(bytes,0,len));
7         }
8         bis.close();
9     }

DataInputStream(基本数据输入流):数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。应用程序可以使用DataOutputStream(数据输出流)写入基本数据类型,然后由DataInputStream(数据输入流)读取基本数据。该类是FileInputStream 的子类。

     byte b = dis.readByte();
        short s = dis.readShort();
        int i = dis.readInt();
        long l = dis.readLong();
        float f = dis.readFloat();
        double d = dis.readDouble();
        char c = dis.readChar();
        boolean bb = dis.readBoolean();

 

四、字节输出流(OutputStream)

 输出:将内存中的数据写入磁盘文件中

OutputStream类是Java IO API中所有输出流的基类,主要是将内存中的数据输入到目标媒介中。

public abstract class OutputStream implements Closeable, Flushable {
   //写入一个字节到stream中
    public abstract void write(int b) throws IOException;
    //把字节数组中所有数据写入到输出流中
    public void write(byte b[]) throws IOException {
        write(b, 0, b.length);
    }
    //把字节数据中从offset位置开始,length个字节的数据写入到输出流。
    public void write(byte b[], int off, int len) throws IOException {
       
    }
    //方法将所有写入到OutputStream的数据冲刷到相应的目标媒介中,即使所有数据都写入到了FileOutputStream,这些数据还是有可能保留在内存的缓冲区中。通过调用flush()方法,可以把缓冲区内的数据刷新到磁盘
    public void flush() throws IOException {
    }

    //结束数据写入时,需要关闭OutputStream
    public void close() throws IOException {
    }

}

FileOutputStream  将数据写入文件

够造函数:FileOutputStream(String name, boolean append) 创建一个向具有指定 name 的文件中写入数据的输出文件流。 (在文件末尾追加写入)
     FileOutputStream(String name) 创建一个向具有指定名称的文件中写入数据的输出文件流。(在文件开头重新写入)

 1 //write(byte[] b) 将 b.length 个字节从指定的 byte 数组写入此输出流
 2     public static void writeByte() throws IOException{
 3         OutputStream os=new FileOutputStream("E:\\javaTest\\1.txt");
 4         String str="中国";
 5         os.write(str.getBytes());
 6         //flush() 刷新此输出流并强制写出所有缓冲的输出字节。
 7         os.flush();
 8         //close() 1、将流对象变为垃圾,便于jvm垃圾回收机制回收 2、通知系统释放与该文件相关的资源
 9         os.close();
10     }
11     //write(int b)  将指定的字节写入此输出流。
12     public static void writeInt() throws IOException{
13         OutputStream os=new FileOutputStream("E:\\javaTest\\1.txt");
14         //我们都知道计算机磁盘存入的是二进制数据,在这里将97当作底层的二进制数据写入磁盘,当我们通过记事本打开文件时,
15         //该文件会根据ASCII字码表进行解码所以我们看到的是字符"a"
16         os.write(97);
17         os.flush();
18         os.close();
19     }
20     //write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
21     public static void writeOffLen() throws IOException{
22         OutputStream os=new FileOutputStream("E:\\test\\javaIo\\1.txt");
23         byte [] bytes="中国".getBytes();
24         os.write(bytes, 0, bytes.length);
25         os.flush();
26         os.close();
27     }
View Code

 BufferedOutputStream 字节输出(写)缓冲流

   字节流一字读写一个数组的速度明显比一次读写一个字节的速度快,这是因为加入了数组缓冲的效果,java设计的本身也考虑到了这种情况(装饰设计模式)所以提供了字节缓冲流(BufferedOutputStream)。该流仅提供缓冲区,是为提高读写效率而设计的。真正操作文件还是需要基本流对象来实现。BufferedOutputStream是 OutputStream的子类具有一切父类的方法。

    public static void bufferOutPutStreamTest() throws IOException{
        BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("E:\\javaTest\\5.txt"));
        bos.write("中".getBytes());
        bos.flush();
        bos.close();
    }

 DataOutputStream(基本数据输出流):数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。该类是FileOutputStream 类的子类。该类提供了写入基础数据类型的方法。

// 写数据了
        dos.writeByte(10);
        dos.writeShort(100);
        dos.writeInt(1000);
        dos.writeLong(10000);
        dos.writeFloat(12.34F);
        dos.writeDouble(12.56);
        dos.writeChar('a');
        dos.writeBoolean(true);

 

五、字节输入流与字节输出流的使用

使用基础字节流实现文件copy:

 1 public  static void readWriter() throws IOException{
 2         String readFileName="D:"+File.separator+"html"+File.separator+"1.txt";
 3         String writerFileName="D:"+File.separator+"html"+File.separator+"2.txt";
 4         InputStream is=new FileInputStream(new File(readFileName));//
 5         OutputStream out=new FileOutputStream(new File(writerFileName));
 6         byte [] b=new byte[1024];
 7         int len=0;
 8         while((len=is.read(b))!=-1){
 9             out.write(b, 0, len);
10         }
11         is.close();
12         out.close();
13     }

 使用字节缓冲流实现文件的copy:

 1 public static void BufferFileCopy() throws IOException{
 2         BufferedInputStream bis=new BufferedInputStream(new FileInputStream("E:\\javaTest\\5.txt"));
 3         BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("E:\\javaTest\\6.txt"));
 4         byte[]bytes=new byte[1024];
 5         int len=0;
 6         while((len=bis.read(bytes))!=-1){
 7             bos.write(bytes, 0, len);
 8         }
 9         bos.flush();
10         bos.close();
11         bis.close();
12     }

 

推荐阅读