JavaSE-10-I/O流

Table of Contents

 

I/O流

1:Path和Paths类

1.1:创建Path对象

1.1.1:通过Paths类来创建Path对象

1.1.2: 通过 FileSystems  类和 和 FileSystem  类建 创建 Path  对象

1.1.3:通过File对象换成Path对象

1.2:Path类的方法

1.2.1:名称

1.2.2:路径

1.2.3:新路径

2:Files类,对文件进行操作

2.1:public boolean isWritable(Path path) 判断文件是否可被写入

2.2:public boolean isExecutable(Path path) 判断文件是否存在

2.3:public static Path createFile(Path path,FileAttribute... attrs) 创建一个新的空文件,如果文件已经存在,则抛出异常

2.4:public static boolean isSameFile(Path p1,Path p2) 判断两个文件是否是同一个文件

2.5:public static long size(Path path) 获取文件的长度,单位是字节

2.6:public static boolean isDirectory(Path path) 测试文件是否为目录

2.7:遍历子文件---只遍历目录下一级

2.7.1:public static Stream list(Path dir)  遍历子文件(只遍历目录下一级)--参数是目录;返回一个 stream 流,其元素是目录中的条目。

2.7.2:public static DirectoryStream newDirectoryStream(Path dir)打开目录,返回一个 DirectoryStream 遍历目录中的所有条目。可以使用迭代器遍历

2.7.3:public static DirectoryStream newDirectoryStream(Path dir,DirectoryStream.Filter filter)) --- 通过 Filter 接口过滤子文件

2.7.4:public static DirectoryStream newDirectoryStream(Path dir,String glob) --- 正则表达式过滤

2.8:遍历目录树---查询目录下所有的文件,包括向里延伸

2.8.1:public static Stream find(Path start,int maxDepth,BiPredicate matcher,FileVisitOption... options)通过在给定的起始文件中,搜索文件树中的文件,返回一个被路径填充的流。,basicfileattributes>

2.8.2:public static Stream walk(Path start,FileVisitOption... options)

2.8.3:public static Path walkFileTree(Path start,FileVisitor visitor)

2.9:创建目录

2.9.1:public static Path createDirectory(Path dir,FileAttribute... attrs)创建一个新的目录,但是父目录必须存在

2.9.2:public static Path createDirectories(Path dir,FileAttribute... attrs)可以先创建不存在的父目录

2.10:删除

2.10.1:public boolean delete(Path path) 删除文件,如果文件不存在,抛异常。

2.10.2:public boolean deleteIfExists() 删除文件(如果存在),如果文件不存在,什么也不做。

2.11:生成字节流InputStream

2.11.1:public static InputStream newInputStream(Path path,OpenOption...options)

2.11.2:public static OutputStream newOutputStream(Path path,OpenOption... options)

2.12:读取字节数组public static byte[] readAllBytes(Path path)从文件中读取所有

字节

2.13:读取字符串public static List readAllLines(Path path)

2.14:写入字符串

2.14.1---public static Path write(Path path,byte[] bytes, OpenOption...options)将字节写入文件

2.14.2:public static Path write(Path path,Iterable lines,OpenOption... options)---将文本行写入文件中

2.15:public static Path move(Path source, Path target,CopyOption...options)将文件移动或重命名为目标文件。

3:流的概念

4: FileInputStream类

4.1:创建文件输入流

4.2:从输入流中读取字节

4.2.1:int read( )

4.2.2:int read(byte[] b)

4.2.3:示例

4.3:关闭流

5:FileOutputStream 类

6:对象字节流

6.1 ObjectInputStream 和 和 ObjectOutputStream

6.2:串行化

7:缓冲字节流

8:数据字节流

9:字符流

9.1:Reader  和 Writer

9.2:缓冲读者和缓冲作者


I/O流

1:Path和Paths类

Path 用于来表示文件路径和文件,用来获取文件本身的一些信息,例如文件所在的目录,文件的长度,文件读写权限等。

1.1:创建Path对象

1.1.1:通过Paths类来创建Path对象

Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
Path path1 = Paths.get("C:\\Users\\86156\\Desktop","test.txt");

1.1.2: 通过 FileSystems  类和 和 FileSystem  类建 创建 Path  对象

Path path2 = FileSystems.getDefault().getPath("C:\\Users\\86156\\Desktop\\test.txt");

1.1.3:通过File对象换成Path对象

File 类是 jdk7 之前的文件类,jdk7 之后被 Path 类替代。

File file = new File("C:\\Users\\86156\\Desktop\\test.txt");
Path path3 = file.toPath();

1.2:Path类的方法

1.2.1:名称

public Path getFileName() ----返回此路径对象表示的文件或目录的名称。

Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
System.out.println(""+path.getFileName());//test.txt

1.2.2:路径

public int getNameCount() --- 返回路径中的文件名称的数目,即该路径一共几层;

Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
int nameCount = path.getNameCount();
System.out.println(""+nameCount);//4

public Path getName(int index) --- 返回路径中指定位置的文件名称

        Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
        int nameCount = path.getNameCount();
        System.out.println(""+nameCount);//4

        Path name0 = path.getName(0);
        Path name1 = path.getName(1);
        Path name2 = path.getName(2);
        Path name3 = path.getName(3);
        System.out.println(""+name0);//Users
        System.out.println(""+name1);//86156
        System.out.println(""+name2);//Desktop
        System.out.println(""+name3);//test.txt

public Path getParent()---返回此路径的父路径,如果该路径没有父路径,则返回 null

        Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
        Path parent = path.getParent();
        System.out.println(""+parent);//C:\Users\86156\Desktop

public Path getRoot() --- 返回此路径的根路径,如果该路径没有根路径,则返回 null

        Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
        Path root = path.getRoot();
        System.out.println(""+root);//C:\

public boolean isAbsolute() --- 如果此路径是绝对路径,则返回 true

        Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
        boolean absolute = path.isAbsolute();
        System.out.println(""+absolute);//true

        Path path1 = Paths.get("hello.txt");
        boolean absolute1 = path1.isAbsolute();
        System.out.println(""+absolute1);//false

1.2.3:新路径

public Path resolve(String path) --- 在此路径下将给定的路径字符串转换为新路径

        Path path = Paths.get("C:\\Users\\86156\\Desktop");
        Path resolve = path.resolve("123");
        System.out.println(""+resolve);//C:\Users\86156\Desktop\123

public Path resolveSibling(String path)在此路径的父路径下将给定的路径字符转成新的路径

        Path path = Paths.get("C:\\Users\\86156\\Desktop");
        Path resolve = path.resolve("123");
        System.out.println(""+resolve);//C:\Users\86156\Desktop\123

        Path resolveSibling = resolve.resolveSibling("456");
        System.out.println(""+resolveSibling);//C:\Users\86156\Desktop\456

 public Path toAbsolutePath()返回此路径的绝对路径

        Path path = Paths.get("hello");
        Path path1 = path.toAbsolutePath();
        System.out.println(""+path1);//F:\idea-workpase\helloidea\hello这是该项目的路径

2:Files类,对文件进行操作

这个类完全由操作文件、目录或其他类型文件的静态方法组成。在大多数情况下,这里定义的方法将委托相关的文件系统提供程序来执行文件操作。

2.1:public boolean isWritable(Path path) 判断文件是否可被写入

//如果文件不存在时不可以写入的        
        Path path = Paths.get("hello.txt");
        Path path1 = path.toAbsolutePath();
        System.out.println(""+path1);//F:\idea-workpase\helloidea\hello.txt这是该项目的路径

        boolean writable = Files.isWritable(path);
        System.out.println(""+writable);//true

2.2:public boolean isExecutable(Path path) 判断文件是否存在

        boolean executable = Files.isExecutable(path);
        System.out.println(""+executable);//true

2.3:public static Path createFile(Path path,FileAttribute<?>... attrs) 创建一个新的空文件,如果文件已经存在,则抛出异常

        Path path = Paths.get("hello1.txt");
        Path file = Files.createFile(path);
        System.out.println(""+file);//hello1.txt

创建文件时,指定文件属性。(Linux)

        Path p1 = Paths.get("hello.txt");
        Set perms= PosixFilePermissions.fromString("rw-rw-rw-");
        FileAttribute attrs = PosixFilePermissions.asFileAttribute(perms);
        Files.createFile(p1,attrs);

2.4:public static boolean isSameFile(Path p1,Path p2) 判断两个文件是否是同
一个文件

        Path path = Paths.get("hello.txt");
        Path path1 = Paths.get("hello1.txt");
        boolean sameFile = Files.isSameFile(path, path1);
        System.out.println(""+sameFile);

2.5:public static long size(Path path) 获取文件的长度,单位是字节

        Path path = Paths.get("hello.txt");
        long size = Files.size(path);
        System.out.println(""+size);

2.6:public static boolean isDirectory(Path path) 测试文件是否为目录

        Path path = Paths.get("hello.txt");
        boolean directory = Files.isDirectory(path);
        System.out.println(""+directory);

2.7:遍历子文件---只遍历目录下一级

2.7.1:public static Stream<Path> list(Path dir)  遍历子文件(只遍历目录下一级)--参数是目录;返回一个 stream 流,其元素是目录中的条目。

2.7.2:public static DirectoryStream<Path> newDirectoryStream(Path dir)打开目录,返回一个 DirectoryStream 遍历目录中的所有条目。可以使用迭代器遍历

        Path path = Paths.get("F:/");
        DirectoryStream<Path> paths = Files.newDirectoryStream(path);
        for(Path file:paths){
            System.out.println(""+file);
        }

2.7.3:public static DirectoryStream<Path> newDirectoryStream(Path dir,
DirectoryStream.Filter<? super Path> filter)) --- 通过 Filter 接口过滤子文件

Path path = Paths.get("F:/");
DirectoryStream<Path> paths = Files.newDirectoryStream(path,p->Files.size(p)>1024);
for(Path file:paths){
   System.out.println(""+file);
}

2.7.4:public static DirectoryStream<Path> newDirectoryStream(Path dir,String glob) --- 正则表达式过滤

        Path path = Paths.get("F:/");
        DirectoryStream<Path> paths = Files.newDirectoryStream(path,"S*");
        for(Path file:paths){
            System.out.println(""+file);
        }

2.8:遍历目录树---查询目录下所有的文件,包括向里延伸

2.8.1:public static Stream<Path> find(Path start,int maxDepth,BiPredicate<Path,BasicFileAttributes> matcher,FileVisitOption... options)通过在给定的起始文件中,搜索文件树中的文件,返回一个被路径填充的流。

start - 起始文件

maxDepth - 要搜索的目录级别的最大数量

matcher - 用于决定文件是否应包含在返回的流中的函数

options - 配置遍历的选项

        Path p1 = Paths.get("F:\\idea-workpase");
        //搜索文件树中满足要求的文件
        Stream<Path> ps= Files.find(p1, Integer.MAX_VALUE,(p,a)->p.endsWith("hello.txt"));
        //循环输出查询结果
        ps.forEach(p->System.out.println(p));

2.8.2:public static Stream<Path> walk(Path start,FileVisitOption... options)

返回一个Stream ,它通过走根据给定起始文件的文件树懒惰地填充Path 。 文件树以深度优先的方式遍历 ,流中的元素是Path对象,如resolving所示 ,相对路径为start

start - 起始文件

options - 配置遍历的选项

这个方法的工作原理就像调用它相当于评估表达式:

 walk(start, Integer.MAX_VALUE, options)

 

        Path p1 = Paths.get("F:\\idea-workpase");
        //搜索文件树中满足要求的文件
        Stream<Path> walk = Files.walk(p1);
        walk.forEach(path -> {System.out.println(""+path);});

 

2.8.3:public static Path walkFileTree(Path start,FileVisitor<? super Path> visitor)

//接口方法的返回值FileVisitResult是一个枚举类型,
//walkFileTree会根据这个返回值决定是否要继续遍历下去,
//它总共有 4 个枚举值:
//CONTINUE:继续遍历
//SKIP_SIBLINGS:继续遍历,但忽略当前节点的所有兄弟节点直接返回上一层继续遍历
//SKIP_SUBTREE:继续遍历,但是忽略子目录,但是子文件还是会访问;
//TERMINATE:终止遍历

public class TestMain {

    public static void main(String[] args) throws IOException {
        Path p1 = Paths.get("F:\\idea-workpase\\helloidea\\src\\timeTask");
        //搜索文件树中满足要求的文件
        //接口方法的返回值FileVisitResult是一个枚举类型,
        //walkFileTree会根据这个返回值决定是否要继续遍历下去
        //CONTINUE:继续遍历
        //SKIP_SIBLINGS:继续遍历,但忽略当前节点的所有兄弟节点直接返回上一层继续遍历
        //SKIP_SUBTREE:继续遍历,但是忽略子目录,但是子文件还是会访问;
        //TERMINATE:终止遍历
        Files.walkFileTree(p1, new FileVisitor<Path>() {
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                //访问目录前
                System.out.println("start");
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                //访问文件时
                System.out.println(""+file.getFileName());
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
                //访问文件失败
                System.out.println("failed:"+file.getFileName());
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                //访问目录后
                System.out.println("end");
                return FileVisitResult.CONTINUE;
            }
        });


    }
}

2.9:创建目录

2.9.1:public static Path createDirectory(Path dir,FileAttribute<?>... attrs)创建一个新的目录,但是父目录必须存在

public static void main(String[] args) throws IOException {
        Path path = Paths.get("F:\\1");
        //如果父类不存在,那么就会跑出异常
        Path directory = Files.createDirectory(path);
        System.out.println(""+directory);


    }

2.9.2:public static Path createDirectories(Path dir,FileAttribute<?>... attrs)可以先创建不存在的父目录

public static void main(String[] args) throws IOException {
        Path path = Paths.get("F:\\1\\2");
        //如果父目录不存在,那么就会先创建父目录
        Path directory = Files.createDirectories(path);
        System.out.println(""+directory);


    }

2.10:删除

2.10.1:public boolean delete(Path path) 删除文件,如果文件不存在,抛异常。

2.10.2:public boolean deleteIfExists() 删除文件(如果存在),如果文件不存在,什么也不做。

2.11:生成字节流InputStream

2.11.1:public static InputStream newInputStream(Path path,OpenOption...options)

打开一个文件,返回一个输入流以从文件中读取文件。

public class Test2 {
    public static void main(String[] args) throws IOException {
        Path path = Paths.get("");
        InputStream inputStream = Files.newInputStream(path);
    }
}

2.11.2:public static OutputStream newOutputStream(Path path,OpenOption... options)

打开或创建一个文件,返回一个输出流,该字节流可用于写入文件的字节。

public class Test2 {
    public static void main(String[] args) throws IOException {
        Path path = Paths.get("");
        OutputStream outputStream = Files.newOutputStream(path);
    }
}

2.12:读取字节数组public static byte[] readAllBytes(Path path)从文件中读取所有

字节

public class Test2 {
    public static void main(String[] args) throws IOException {
        Path path = Paths.get("");
        byte[] bytes = Files.readAllBytes(path);
    }
}

2.13:读取字符串public static List<String> readAllLines(Path path)

public class Test2 {
    public static void main(String[] args) throws IOException {
        Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
        List<String> strings = Files.readAllLines(path);
        for(String str:strings){
            System.out.println(""+str);
        }
    }
}

2.14:写入字符串

2.14.1---public static Path write(Path path,byte[] bytes, OpenOption...options)将字节写入文件

public class Test2 {
    public static void main(String[] args) throws IOException {
        Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
        //追加
        Path write = Files.write(path, "4444444444".getBytes(), StandardOpenOption.APPEND);

    }
}

2.14.2:public static Path write(Path path,Iterable<? extends CharSequence> lines,
OpenOption... options)---将文本行写入文件中

public class Test2 {
    public static void main(String[] args) throws IOException {
        Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
        List<String> list = new ArrayList<>();
        list.add("aaaaa");
        list.add("bbbbb");
        //追加
        Path write = Files.write(path,list , StandardOpenOption.APPEND);

    }
}

2.15:public static Path move(Path source, Path target,CopyOption...options)
将文件移动或重命名为目标文件。

public class Test2 {
    public static void main(String[] args) throws IOException {
        Path path = Paths.get("C:\\Users\\86156\\Desktop\\test.txt");
        Path path1 = Paths.get("C:\\Users\\86156\\Desktop\\test1.txt");
        Path copy = Files.copy(path, path1);

    }
}

3:流的概念

流是字节从源到目的的轨迹,次序是有意义的。

4: FileInputStream类

如果需要从本地硬盘读取文件,可以使用 FileInputStream 类,该类是从 InputStream中派生出来的简单输入类。该类的所有方法都是从 InputStream 类继承来的。为了创建FileInputStream 类的对象,可以调用下面两个构造方法:

  •  FileInputStream(String name)
  •  FileInputStream(File file)

第一个构造器使用给定的文件名 name 创建一个 FileInputStream 对象,第二个构造器使用 File 对象创建 FileInputStream 对象。

4.1:创建文件输入流

public class Test2 {
    public static void main(String[] args) throws IOException {
        File file = new File("C:\\Users\\86156\\Desktop\\test.txt");
        FileInputStream fileInputStream = new FileInputStream(file);
    }
}

4.2:从输入流中读取字节

输入流的唯一目的是提供通往数据的通道,程序可以通过这个通道读取数据。Read 方法给程序提供一个从输入流中读取数据的基本方法

4.2.1:int read( )

从输入流中读取数据的下一个字节。返回  0 到  255 范围内的  int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值  -1 。

4.2.2:int read(byte[] b)

从输入流中读取一定数量的字节,并将其存储在缓冲区数组  b 中。以整数形式返回实际读取的字节数。如果遇到输入流的结尾,则返回 -1 。

FileInputStream 流顺序地读取文件,只要不关闭流,每次调用 read 方法就顺序地读取源其余的内容,直到流的末尾或流被关闭。

4.2.3:示例

public class Test2 {
    public static void main(String[] args) throws IOException {
        File file = new File("C:\\Users\\86156\\Desktop\\test.txt");
        FileInputStream fileInputStream = new FileInputStream(file);
        byte[] b =new byte[20];
        int i=0;
        while ((i=fileInputStream.read(b))!=(-1)){
            System.out.println(""+i);
            System.out.println(""+ Arrays.toString(b));
        }
    }
}

4.3:关闭流

我们使用完流后,显式地关闭任何打开的流仍是一个良好的习惯。

public class Test2 {
    public static void main(String[] args){
        FileInputStream fileInputStream = null;
        try {
            File file = new File("C:\\Users\\86156\\Desktop\\test.txt");
            fileInputStream = new FileInputStream(file);
            byte[] b =new byte[20];
            int i=0;
            while ((i=fileInputStream.read(b))!=(-1)){
                System.out.println(""+i);
                System.out.println(""+ new String(b));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

5:FileOutputStream 类

与 FileInputStream 类相对应的类是 FileOutputStream 类。FileOutputStream 提供了基本的文件写入能力。FileOutputStream 类有两个构造方法:

  • FileOutputStream(String name)
  • FileOutputStream(File file)

FileOutputStream 类有三个基本的 write()方法

  • void write(int n)
  • void write(byte b[])
  • void write(byte b[], int off, int len)

这些方法写输出流。和输入一样,总是尝试以实际最大的块进行写操作

  • void close()

当你完成写操作后,就关闭输出流。如果你有一个流所组成的栈,就关闭栈顶部的流。 这个关闭操作会关闭其余的流

  • void flush()

有时一个输出流在积累了若干次之后才进行真正的写操作。flush()方法允许你强制执行写操作。

public class Test2 {
    public static void main(String[] args){
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        try {
            File file = new File("C:\\Users\\86156\\Desktop\\test.txt");
            fileInputStream = new FileInputStream(file);
            fileOutputStream = new FileOutputStream(new File("C:\\Users\\86156\\Desktop\\testhello.txt"));
            byte[] b =new byte[20];
            int i=0;
            while ((i=fileInputStream.read(b))!=(-1)){
                System.out.println(""+i);
                System.out.println(""+ new String(b));
                fileOutputStream.write(b,0,i);
                fileOutputStream.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                fileInputStream.close();
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

6:对象字节流

6.1 ObjectInputStream 和 和 ObjectOutputStream

ObjectInputStream 类 和 ObjectOutputStream 类 分 别 是 InputStream 类 和OutputStream 类的子类。ObjectInputStream 类和 ObjectOutputStream 类创建的对象被称为对象输入流和对象输出流。

对象输出流使用 writeObject(Object obj)方法将一个对象 obj 写入到一个文件,对象输入流使用 readObject()读取一个对象到程序中。ObjectInputStream 类和 ObjectOutputStream 类的构造方法分别是:

  • ObjectInputStream(InputStream in)
  • ObjectOutputStream(OutputStream out)

示例:

public class Test3 {
    public static void main(String[] args) {
        File file = new File("C:\\Users\\86156\\Desktop\\date.txt");
        FileOutputStream fileOutputStream = null;
        ObjectOutputStream objectOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(file);
            objectOutputStream = new ObjectOutputStream(fileOutputStream);
            objectOutputStream.writeObject(new Date());

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                objectOutputStream.close();
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

6.2:串行化

将一个对象存放到某种类型的永久存储器上称为保持。如果一个对象可以被存放到磁盘或磁带上,或者可以发送到另外一台机器并存放到存储器或磁盘上,那么这个对象就被称为可保持的。java.io.Serializable 接口没有任何方法,它只作为一个“标记者”,用来表明实现了这个接口的类可以考虑串行化。类中没有实现 Serializable 的对象不能保存或恢复它们的状态。

串行化的类必须实现:Serializable接口

public class MyClass implements Serializable {

7:缓冲字节流

java.io.BufferedInputStream 与 java.io.BufferedOutputStream 可 以 为InputStream、OutputStream 类增加缓冲区功能。构建 BufferedInputStream 实例时,需要给定一个 InputStream 类型的实例,实现 BufferedInputStream 时,实际上最后是实
现 InputStream 实例。

BufferedInputStream 的数据成员 buf 是一个位数组,默认为 2048 字节。当读取数据来源时,例如文件,BufferedInputStream 会尽量将 buf 填满。当使用 read()方法时,实际上是先读取 buf 中的数据,而不是直接对数据来源作读取。当 buf 中的数据不足时,BufferedInputStream 才会再实现给定的 InputStream 对象的 read()方法,从指定的装置中提取数据。

public class Test2 {
    public static void main(String[] args){
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        BufferedInputStream bufferedInputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        try {
            File file = new File("C:\\Users\\86156\\Desktop\\test.txt");
            fileInputStream = new FileInputStream(file);
            fileOutputStream = new FileOutputStream(new File("C:\\Users\\86156\\Desktop\\testhello.txt"));
            bufferedInputStream = new BufferedInputStream(fileInputStream);
            bufferedOutputStream = new BufferedOutputStream(fileOutputStream);

            byte[] b =new byte[20];
            int i=0;
            while ((i=bufferedInputStream.read(b))!=(-1)){
                System.out.println(""+i);
                System.out.println(""+ new String(b));
                bufferedOutputStream.write(b,0,i);
                bufferedOutputStream.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                fileInputStream.close();
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

8:数据字节流

DataInputStream 类 和 DataOutputStream 类创建的对象被称为数据输入流和数据输出流。数据流允许程序按照机器无关的风格读取操作数据,也就是当我们操作一个数据时,不必关心这个数值应当是多少个字节。

操作与上述类似,不同的是直接对读写的类型进行操作;

9:字符流

9.1:Reader  和 Writer

Java 技术使用 Unicode 来表示字符串和字符,而且它提供了 16 位版本的流,以便用类似的方法来处理字符。这些 16 位版本的流称为读者和作者。和流一样,它们都在 java.io包中。 读者和作者中最重要的版本是 InputStreamReader 和 OutputStreamWriter。这些类用来作为字节流与读者和作者之间的接口。

字符流在进行中文操作时会更加方便和准确,比如在读取中文文档内容时,字节流可能会读取到中文的一半,而字符流则不会出现这样的问题。

这样用字节流读,中文有可能是乱码;

FileInputStream fis = null;
try {
    File f = new File("test.txt");
    // 创建字节流
    fis = new FileInputStream(f);
    // 创建字节数组,每次读取 5 个字节
    byte[] arr = new byte[5];
    // 读取的字节长度
    int length=0;
    while((length=fis.read(arr))!=-1){
        // 将读取的数据转换成String
        String msg = new String(arr,0,length);
        //输出
        System.out.print(msg);
    }
} catch (IOException e) {
    // 文件不存在异常
    System.out.println("File read error:" + e);
} finally {    
    if (fis != null) {
    try {
        fis.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    }
}

但是用字符流读,就没事

FileInputStream fis = null;
InputStreamReader reader = null;
try {
    File f = new File("test.txt");
    // 创建字节流
    fis = new FileInputStream(f);
    // 创建字符流
    reader = new InputStreamReader(fis);
    // 创建字符数组,每次读取 5 个字符
    char[] arr = new char[5];
    // 读取的字符长度
    int length = 0;
    while ((length = reader.read(arr)) != -1) {
    // 将读取的数据转换成String
    String msg = new String(arr, 0, length);
    // 输出
    System.out.print(msg);
    }
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (reader != null) {
    try {
        reader.close();
} catch (IOException e) {
    e.printStackTrace();
    }
    }
}

9.2:缓冲读者和缓冲作者

他们和InputStreamReader 以及OutputStreamReader的区别就在于,他们有一个长度为8192字节的char[]数组,每次写文件都是先向缓冲区中写入,等缓冲区满了,则数据写入硬盘,如果没满,继续等待,如果最中没慢,需要关闭流后者fulsh流,也会把数据写入硬盘; 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苍煜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值