java IO流的一些常用操作

    xiaoxiao2022-07-03  142

    java i/o 的一些操作

    文件流:FileInputStream/FileOutputStream, FileReader/FileWriter

    这四个类是专门操作文件流的,用法高度相似,区别在于前面两个是操作字节流,后面两个是操作字符流。它们都会直接操作文件流,直接与OS底层交互。因此他们也被称为节点流。 package com.lw.study.excelTest; import com.lw.study.Application; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.io.*; /** * @author: * @Date: 15:21 2019/2/28 */ @SpringBootTest(classes = Application.class) @RunWith(SpringJUnit4ClassRunner.class) public class FileTest { // 字节流没有缓冲区,是直接输出的,而字符流是输出到缓冲区的。因此在输出时,字节流不调用colse()方法时,信息已经输出了, // 而字符流只有在调用close()方法关闭缓冲区时,信息才输出。要想字符流在未关闭时输出信息,则需要手动调用flush()方法。 @Test public void testGetFile() throws IOException { //字节流 String filepath = "/tmp/dashu/test.txt"; OutputStream outputStream = new FileOutputStream("/tmp/dashu/test3.txt"); InputStream inputStream = new FileInputStream(filepath); try { byte[] b = new byte[inputStream.available()]; System.out.println(inputStream.available()); inputStream.read(b); System.out.println(new String(b)); outputStream.write(b); } catch (FileNotFoundException e) { e.printStackTrace(); }finally { inputStream.close(); outputStream.close(); } } @Test public void testWrite() { //字符流 try { //若文件不存在会新建一个文件,然后写入内容,文件存在覆盖源文件内容 FileWriter fw = new FileWriter("/tmp/dashu/test4.txt"); FileReader fd = new FileReader("/tmp/dashu/test2.txt"); char[] read = new char[32]; int hasRead = 0; while ( (hasRead =fd.read(read)) > 0) { // System.out.println(read); String readLine = new String(read, 0, hasRead); System.out.println(readLine); //一定要关闭这个溜。不然会写不进去 //关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据。 //将数据刷到目的地中去。 //和flush区别:flush 刷新后,流可以继续使用,close刷新后,会将流关闭。 // 实际上,当我们写好了new FileWriter 的时候,我们进行下一步的操作,将数据写入文本,但是这时的数据并没有写入文本,而是存在了计算机中的流中。这也是JAVA能够在Windows 系统中调用文本流的作用。而如果在这里我们使用fw.flush时,是可以将存储在计算机流中的数据放入fw的,但是如果我们之后再想加入数据的时候,也就是说我们将写入的数据这句话放在fw.flush之后的话,之后输入的数据就不会放入到 test.txt中去。 // 再说一说fw.close, 我们可以去查询close的定义,很明确的写了 先刷新一次,然后关闭数据流。没错,事实上,close是包含了两步,flush 和close 这两步。所以我们注释掉了flush 因为在这里一个close语句就够用了。 // flush 刷新后,流可以继续使用,close刷新后,会将流关闭。 // fw.write(readLine); fw.close(); } } catch (IOException e) { e.printStackTrace(); } } /** * 字符缓冲流 用来读取纯文本文件 * @throws IOException */ @Test public void testBufferReader() throws IOException { try { BufferedReader bufferedReader = new BufferedReader(new FileReader("/tmp/dashu/test.txt")); BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("/tmp/dashu/test5.txt")); //保存每次读取的一行的内容 String line = ""; while ((line = bufferedReader.readLine()) != null) { System.out.println(line); bufferedWriter.write(line); //换行 bufferedWriter.newLine(); } bufferedReader.close(); bufferedWriter.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } } /** *字节缓冲流,读取图片、视频等 * @throws IOException */ @Test public void testBufferInputStream() throws IOException { BufferedInputStream in = new BufferedInputStream(new FileInputStream("/tmp/dashu/终端背景.jpg")); BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("/tmp/dashu/终端背景2.jpg")); byte[] bRead = new byte[in.available()]; in.read(bRead); out.write(bRead); in.close(); out.close(); } }

    总结几种流的应用场景:

    FileInputStream/FileOutputStream 需要逐个字节处理原始二进制流的时候使用,效率低下FileReader/FileWriter 需要组个字符处理的时候使用StringReader/StringWriter 需要处理字符串的时候,可以将字符串保存为字符数组PrintStream/PrintWriter 用来包装FileOutputStream 对象,方便直接将String字符串写入文件Scanner 用来包装System.in流,很方便地将输入的String字符串转换成需要的数据类型InputStreamReader/OutputStreamReader , 字节和字符的转换桥梁,在网络通信或者处理键盘输入的时候用BufferedReader/BufferedWriter , BufferedInputStream/BufferedOutputStream , 缓冲流用来包装字节流后者字符流,提升IO性能,BufferedReader还可以方便地读取一行,简化编程。StringBufferInputStream – 把一个 String 对象作为。InputStream。不建议使用,在转换字符的问题上有缺陷

    注意:

    available()来获取文件的总大小,这个方法在获取本地文件的时候没啥问题,但是如果是获取网络文件的大小,如果网络阻塞了,inputstream已经打开,但是数据却还没有传输过来,那么这个inputstream势必会被阻塞,从而导致inputstream.available返回0。而对inputstream.read(byte[] b)而言,如果b的长度等于0,该方法将返回0。可以考虑手工设定一个固定值;或者读取http报文头的content-length属性值,后一种方式:

    URLConnection openConnection = new URL("http://www.apache.org").openConnection(); System.out.println(openConnection.getContentLength());

    available()这个方法其实是通过文件描述符获取文件的总大小,而并不是事先将磁盘上的文件数据全部读入流中,再获取文件总大小。

    最新回复(0)