Java程序员的日常—— IOUtils总结

简介:

以前写文件的复制很麻烦,需要各种输入流,然后读取line,输出到输出流...其实apache.commons.io里面提供了输入流输出流的常用工具方法,非常方便。下面就结合源码,看看IOUTils都有什么用处吧!
代码参考https://github.com/xinghalo/JDK-Learning

常用的静态变量

在IOUtils中还是有很多常用的一些变量的,比如换行符等等


public static final char DIR_SEPARATOR_UNIX = '/';
public static final char DIR_SEPARATOR_WINDOWS = '\\';
public static final char DIR_SEPARATOR;
public static final String LINE_SEPARATOR_UNIX = "\n";
public static final String LINE_SEPARATOR_WINDOWS = "\r\n";
public static final String LINE_SEPARATOR;


static {
    DIR_SEPARATOR = File.separatorChar;
    
    StringBuilderWriter buf = new StringBuilderWriter(4);
    PrintWriter out = new PrintWriter(buf);
    out.println();
    LINE_SEPARATOR = buf.toString();
    out.close();
}

常用方法

copy

这个方法可以拷贝流,算是这个工具类中使用最多的方法了。支持多种数据间的拷贝:

copy(inputstream,outputstream)
copy(inputstream,writer)
copy(inputstream,writer,encoding)
copy(reader,outputstream)
copy(reader,writer)
copy(reader,writer,encoding)

copy内部使用的其实还是copyLarge方法。因为copy能拷贝Integer.MAX_VALUE的字节数据,即2^31-1。

copyLarge

这个方法适合拷贝较大的数据流,比如2G以上。

copyLarge(reader,writer) 默认会用1024*4的buffer来读取
copyLarge(reader,writer,buffer)

内部的细节可以参考:

 public static long copyLarge(Reader input, Writer output, char [] buffer) throws IOException {
        long count = 0;
        int n = 0;
        while (EOF != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
            count += n;
        }
        return count;
    }

这个方法会用一个固定大小的Buffer,持续不断的读取数据,然后写入到输出流中。

read

从一个流中读取内容

read(inputstream,byte[])
read(inputstream,byte[],offset,length) 
//offset是buffer的偏移值,length是读取的长度

read(reader,char[])
read(reader,char[],offset,length)

这里我写了个小例子,可以测试read方法的效果:

@Test
    public void readTest(){
        try{
            byte[] bytes = new byte[4];
            InputStream is = IOUtils.toInputStream("hello world");
            IOUtils.read(is, bytes);
            System.out.println(new String(bytes));

            bytes = new byte[10];
            is = IOUtils.toInputStream("hello world");
            IOUtils.read(is, bytes, 2, 4);
            System.out.println(new String(bytes));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

得到的结果是:

hell
□□hell□□□□

readFully

这个方法会读取指定长度的流,如果读取的长度不够,就会抛出异常

readFully(inputstream,byte[])
readFully(inputstream,byte[],offset,length)
readFully(reader,charp[])
readFully(reader,char[],offset,length)

比如:

@Test
    public void readFullyTest(){
        byte[] bytes = new byte[4];
        InputStream is  = IOUtils.toInputStream("hello world");
        try {
            IOUtils.readFully(is,bytes);
            System.out.println(new String(bytes));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

输出

hell

但是如果读取20个byte,就会出错了

java.io.EOFException: Length to read: 20 actual: 11
    at org.apache.commons.io.IOUtils.readFully(IOUtils.java:2539)
    at org.apache.commons.io.IOUtils.readFully(IOUtils.java:2558)
    at test.java.IOUtilsTest.readFullyTest(IOUtilsTest.java:22)
    ...

readLines

readLines方法可以从流中读取内容,并转换为String的list

readLines(inputstream)
readLines(inputstream,charset)
readLines(inputstream,encoding)
readLines(reader)

这个方法极大简化了之前原始的读取方法:

 @Test
    public void readLinesTest(){
        try{
            InputStream is = new FileInputStream("D://test1.txt");
            List<String> lines = IOUtils.readLines(is);
            for(String line : lines){
                System.out.println(line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

输出内容:

hello
world

nihao
ioutils

skip

这个方法用于跳过指定长度的流,

skip(inputstream,skip_length)
skip(ReadableByteChannel,skip_length)
skip(reader,skip_length)

例如:

@Test
    public void skipTest(){
        InputStream is = IOUtils.toInputStream("hello world");
        try {
            IOUtils.skip(is,4);
            System.out.println(IOUtils.toString(is,"utf-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

skipFully

这个方法类似skip,只是如果忽略的长度大于现有的长度,就会抛出异常

skipFully(inputstream,toSkip)
skipFully(readableByteChannel,toSkip)
skipFully(inputstream,toSkip)

例如

@Test
    public void skipFullyTest(){
        InputStream is = IOUtils.toInputStream("hello world");
        try {
            IOUtils.skipFully(is,30);
            System.out.println(IOUtils.toString(is,"utf-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

write

这个方法可以把数据写入到输出流中

write(byte[] data, OutputStream output)
write(byte[] data, Writer output)
write(byte[] data, Writer output, Charset encoding)
write(byte[] data, Writer output, String encoding)
write(char[] data, OutputStream output)
write(char[] data, OutputStream output, Charset encoding)
write(char[] data, OutputStream output, String encoding)
write(char[] data, Writer output)
write(CharSequence data, OutputStream output)
write(CharSequence data, OutputStream output, Charset encoding)
write(CharSequence data, OutputStream output, String encoding)
write(CharSequence data, Writer output)
write(StringBuffer data, OutputStream output)
write(StringBuffer data, OutputStream output, String encoding)
write(StringBuffer data, Writer output)
write(String data, OutputStream output)
write(String data, OutputStream output, Charset encoding)
write(String data, OutputStream output, String encoding)
write(String data, Writer output)

例如

@Test
    public void writeTest(){
        try {
            OutputStream os = new FileOutputStream("E:/test.txt");
            IOUtils.write("hello write!",os);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

writeLines

这个方法可以把string的List写入到输出流中

writeLines(Collection<?> lines, String lineEnding, OutputStream output)
writeLines(Collection<?> lines, String lineEnding, OutputStream output, Charset encoding)
writeLines(Collection<?> lines, String lineEnding, OutputStream output, String encoding)
writeLines(Collection<?> lines, String lineEnding, Writer writer)

例如

@Test
    public void writeLinesTest() throws IOException {
        List<String> lines = new ArrayList();
        lines.add("hello");
        lines.add("list");
        lines.add("to");
        lines.add("file");
        OutputStream os = new FileOutputStream("E:/test.txt");
        IOUtils.writeLines(lines,IOUtils.LINE_SEPARATOR,os);
    }

close

关闭URL连接

close(URLConnection conn)

closeQuietly

忽略nulls和异常,关闭某个流

close(URLConnection conn)
closeQuietly(Closeable... closeables)
closeQuietly(Closeable closeable)
closeQuietly(InputStream input)
closeQuietly(OutputStream output)
closeQuietly(Reader input)
closeQuietly(Selector selector)
closeQuietly(ServerSocket sock)
closeQuietly(Socket sock)
closeQuietly(Writer output)

contentEquals

比较两个流是否相同

contentEquals(InputStream input1, InputStream input2)
contentEquals(Reader input1, Reader input2)

例如

@Test
    public void contentEqualsTest(){
        InputStream is1 = IOUtils.toInputStream("hello123");
        InputStream is2 = IOUtils.toInputStream("hello123");

        try {
            System.out.println(IOUtils.contentEquals(is1,is2));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

contentEqualsIgnoreEOL

比较两个流,忽略换行符

contentEqualsIgnoreEOL(Reader input1, Reader input2)

lineIterator

读取流,返回迭代器

lineIterator(InputStream input, Charset encoding)
lineIterator(InputStream input, String encoding)
lineIterator(Reader reader)

toBufferedInputStream

把流的全部内容放在另一个流中

toBufferedInputStream(InputStream input)
toBufferedInputStream(InputStream input, int size)

toBufferedReader

返回输入流

toBufferedReader(Reader reader)
toBufferedReader(Reader reader, int size)

toByteArray

返回字节数组

toByteArray(InputStream input)
toByteArray(InputStream input, int size)
toByteArray(InputStream input, long size)
toByteArray(Reader input)
toByteArray(Reader input, Charset encoding)
toByteArray(Reader input, String encoding)
toByteArray(String input)
toByteArray(URI uri)
toByteArray(URL url)
toByteArray(URLConnection urlConn)

toCharArray

返回字符数组

toCharArray(InputStream is)
toCharArray(InputStream is, Charset encoding)
toCharArray(InputStream is, String encoding)
toCharArray(Reader input)

toInputStream

返回输入流

toInputStream(CharSequence input)
toInputStream(CharSequence input, Charset encoding)
toInputStream(CharSequence input, String encoding)
toInputStream(String input)
toInputStream(String input, Charset encoding)
toInputStream(String input, String encoding)

toString

返回字符串

toString(byte[] input)
toString(byte[] input, String encoding)
toString(InputStream input)
toString(InputStream input, Charset encoding)
toString(InputStream input, String encoding)
toString(Reader input)
toString(URI uri)
toString(URI uri, Charset encoding)
toString(URI uri, String encoding)
toString(URL url)
toString(URL url, Charset encoding)
toString(URL url, String encoding)
本文转自博客园xingoo的博客,原文链接:Java程序员的日常—— IOUtils总结,如需转载请自行联系原博主。
相关文章
|
18天前
|
Java 程序员
JAVA程序员的进阶之路:掌握URL与URLConnection,轻松玩转网络资源!
在Java编程中,网络资源的获取与处理至关重要。本文介绍了如何使用URL与URLConnection高效、准确地获取网络资源。首先,通过`java.net.URL`类定位网络资源;其次,利用`URLConnection`类实现资源的读取与写入。文章还提供了最佳实践,包括异常处理、连接池、超时设置和请求头与响应头的合理配置,帮助Java程序员提升技能,应对复杂网络编程场景。
42 9
|
3月前
|
存储 算法 Java
惊!Java程序员必看:JVM调优揭秘,堆溢出、栈溢出如何巧妙化解?
【8月更文挑战第29天】在Java领域,JVM是代码运行的基础,但需适当调优以发挥最佳性能。本文探讨了JVM中常见的堆溢出和栈溢出问题及其解决方法。堆溢出发生在堆空间不足时,可通过增加堆空间、优化代码及释放对象解决;栈溢出则因递归调用过深或线程过多引起,调整栈大小、优化算法和使用线程池可有效应对。通过合理配置和调优JVM,可确保Java应用稳定高效运行。
140 4
|
3月前
|
算法 Java 程序员
在Java的编程世界里,多态不仅仅是一种代码层面的技术,它是思想的碰撞,是程序员对现实世界复杂性的抽象映射,是对软件设计哲学的深刻领悟。
在Java的编程世界里,多态不仅仅是一种代码层面的技术,它是思想的碰撞,是程序员对现实世界复杂性的抽象映射,是对软件设计哲学的深刻领悟。
68 9
|
3月前
|
Java 程序员
Java数据类型:为什么程序员都爱它?
Java数据类型:为什么程序员都爱它?
52 1
|
3天前
|
SQL 存储 Java
面向 Java 程序员的 SQLite 替代品
SQLite 是轻量级数据库,适用于小微型应用,但其对外部数据源支持较弱、无存储过程等问题影响了开发效率。esProc SPL 是一个纯 Java 开发的免费开源工具,支持标准 JDBC 接口,提供丰富的数据源访问、强大的流程控制和高效的数据处理能力,尤其适合 Java 和安卓开发。SPL 代码简洁易懂,支持热切换,可大幅提高开发效率。
|
15天前
|
SQL Java 程序员
倍增 Java 程序员的开发效率
应用计算困境:Java 作为主流开发语言,在数据处理方面存在复杂度高的问题,而 SQL 虽然简洁但受限于数据库架构。SPL(Structured Process Language)是一种纯 Java 开发的数据处理语言,结合了 Java 的架构灵活性和 SQL 的简洁性。SPL 提供简洁的语法、完善的计算能力、高效的 IDE、大数据支持、与 Java 应用无缝集成以及开放性和热切换特性,能够大幅提升开发效率和性能。
|
21天前
|
IDE Java 程序员
C++ 程序员的 Java 指南
一个 C++ 程序员自己总结的 Java 学习中应该注意的点。
20 5
|
1月前
|
Java 大数据 程序员
我的程序员之路:自学Java篇
我的程序员之路:自学Java篇
|
4月前
|
Java 程序员 C++
大牛程序员用Java手写JVM:刚好够运行 HelloWorld
大牛程序员用Java手写JVM:刚好够运行 HelloWorld
|
3月前
|
安全 Java 程序员
阿里开发手册 嵩山版-编程规约 (四)OOP规约-Java程序员必看知识点!!!
《阿里开发手册 嵩山版》的OOP规约部分强调了面向对象编程的最佳实践,包括正确使用静态方法、覆写方法的注解、可变参数的使用、接口的稳定性、equals和compareTo方法的使用、BigDecimal的正确比较、包装类与基本数据类型选择、POJO类的属性和方法设计等,以提升代码的质量和维护性。