Java IO

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java IO相关的知识,希望对你有一定的参考价值。

File类

file类指代的应该说是文件集,包含文件集中所有文件的信息,而不是内容.因此file类无法承担读取内容写入内容的任务

常用方法:

  • getName()
  • getPath()
  • getParent()
  • getAbsolutePath()
  • isFile()
  • isDirectory
  • list()
  • listFlie()
    list()方法可以接受一个FilenameFilter对象,用以筛选文件,FilenameFilter接口只有一个方法就是accept(File dir,String name);

输入和输出

字节流

  • java.io.InputStream (implements java.io.Closeable)

    • java.io.ByteArrayInputStream
    • java.io.FileInputStream
    • java.io.FilterInputStream
      • java.io.BufferedInputStream
      • java.io.DataInputStream (implements java.io.DataInput)
      • java.io.LineNumberInputStream
      • java.io.PushbackInputStream
    • java.io.ObjectInputStream (implements java.io.ObjectInput, java.io.ObjectStreamConstants)
    • java.io.PipedInputStream
    • java.io.SequenceInputStream
    • java.io.StringBufferInputStream
  • java.io.OutputStream (implements java.io.Closeable, java.io.Flushable)

    • java.io.ByteArrayOutputStream
    • java.io.FileOutputStream
    • java.io.FilterOutputStream
      • java.io.BufferedOutputStream
      • java.io.DataOutputStream (implements java.io.DataOutput)
      • java.io.PrintStream (implements java.lang.Appendable, java.io.Closeable)
      • java.io.ObjectOutputStream (implements java.io.ObjectOutput, java.io.ObjectStreamConstants)
      • java.io.PipedOutputStream

io库中输入输出的类全部继承于这两个类,继承于inputStream的类必然有read()方法,outputStream则必然有write()方法.

FilterInputStream和FilterOutputStream分别继承自inputStream和OutputStream,为其余的装饰器类提供基类

字符流

  • java.io.Writer (implements java.lang.Appendable, java.io.Closeable, java.io.Flushable)

    • java.io.BufferedWriter
    • java.io.CharArrayWriter
    • java.io.FilterWriter
    • java.io.OutputStreamWriter
      • java.io.FileWriter
    • java.io.PipedWriter
    • java.io.PrintWriter
    • java.io.StringWriter
  • java.io.Reader (implements java.io.Closeable, java.lang.Readable)

    • java.io.BufferedReader
      • java.io.LineNumberReader
    • java.io.CharArrayReader
    • java.io.FilterReader
      • java.io.PushbackReader
    • java.io.InputStreamReader
      • java.io.FileReader
    • java.io.PipedReader
    • java.io.StringReader

Reader和Writer提供兼容Unicode和面向字符的I/O功能

独立的类RandomAccessFile

它并不继承inputStream或是outputstream 而是仅仅实现了dataInput和dataOutput接口,他是一个完全独立的类,从头开始编写其所有的方法.它支持对文件的随机访问读写,使用时使用第二个参数指示随机读(r)还是读写(rw),并不支持只写.使用seek()移动文件指针.length()判断文件最大尺寸.

IO流的典型使用方式

缓冲输入文件

可以使用FileInputReader,为了提高速度,进行缓冲,我们把fileInputReader的引用传递给bufferedReader,使用bufferedReader的readLine()方法进行文件读取.

public static String read(String filename) throws IOException {
    if (filename.equals(""))
        filename = "C:\\renluxiang\\code\\java\\thinking in java\\java\\DirList3.java";
    BufferedReader bufferedReader = new BufferedReader(new FileReader(filename));
    StringBuilder sb = new StringBuilder();
    String s;
    while ((s = bufferedReader.readLine()) != null) {
        sb.append(s + "\n");
    }
    bufferedReader.close();
    return sb.toString();
}

从内存输入

StringReader可以用来读取内存中的数据,但是read()方法返回的是int,需要类型转换为char才能正确打印.

public static void main(String[] args) throws IOException {
    StringReader stringReader = new StringReader(BufferedInputFile.read(""));
    int i;
    while ((i = stringReader.read()) != -1) {
        System.out.print((char) i);
    }
}

格式化的内存输入

读取格式化数据,可以使用DatainputStream,这是面向字节的I/O类,要读取字节必须使用inputStream而不是Reader.使用readbyte()时因为一次一个字节读取,因此无法以返回值检测是否结束,可以使用available()方法获得还有多少字符以此判断输入结束.

但是available()方法在不同的流下有不同的作用,因此要谨慎使用.

public static void main(String[] args) throws IOException {
    DataInputStream in = new DataInputStream(new ByteArrayInputStream(BufferedInputFile.read("")
            .getBytes()));
    try {
        while (in.available() != 0) {
            System.out.print((char) in.readByte());
        }
    } catch (Exception e) {
        System.err.println("end of stream");
    }

}

基本的文件输出

要向文件中写入字符数据需要使用fileWriter,而为了性能考虑一般要再将它包装为bufferedWriter,然后在包装为别的writer子类

如下:

PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(file)));
// java se5加入了辅助构造器 所以可以这样写
// PrintWriter out = new PrintWriter(file);

存储和恢复数据

为了可以输出供另一个流恢复的数据,需要dataOutputStream,并用DataInputStream回复.使用dataOutputstream和dataInputStream java会保证无论读和写的平台多么不同,都不会影响数据的回复.

而且有writeUTF()和readUTF()的支持,可以随意的将字符串与其他内容进行混合输出,因为字符串的长度存储在了字符串前两个字节中,可以保证字符串的原样读入

public static void main(String[] args) throws IOException {
    DataOutputStream out = new DataOutputStream(new FileOutputStream("out\\data.txt"));
    out.writeDouble(3.14);
    out.writeUTF("任鲁翔");
    out.close();
    DataInputStream in = new DataInputStream(
            new BufferedInputStream(
                    new FileInputStream("out\\data.txt")));
    System.out.println(in.readDouble());
    System.out.println(in.readUTF());
    in.close();
}

读写随机访问文件

使用RandomAccessFile对文件进行操作

public static void main(String[] args) throws IOException {
    File demo = new File("out");
    if (!demo.exists())
        demo.mkdir();
    File file = new File(demo, "raf.txt");
    if (!file.exists())
        file.createNewFile();
    RandomAccessFile raf = new RandomAccessFile(file, "rw");
    System.out.println(raf.getFilePointer());
    raf.writeChars("a");
    raf.writeChars("b");
    System.out.println(raf.getFilePointer());
    int i = 0x7fffffff;
    raf.write(i >>> 24);
    raf.write(i >>> 16);
    raf.write(i >>> 8);
    raf.write(i);

    String s = "任鲁翔";
    byte[] bytes = s.getBytes("UTF-8");
    raf.write(bytes);

    raf.seek(0);
    byte[] buf = new byte[(int) raf.length()];
    raf.read(buf);

    System.out.println(buf.toString());
}

读取二进制文件

public static byte[] read(File bfile) throws IOException {
byte[] data = null;
BufferedInputStream bf = new BufferedInputStream(new FileInputStream(bfile));
try {
data = new byte[bf.available()];
bf.read(data);
} catch (IOException e) {
e.printStackTrace();
}finally {
bf.close();
}
return data;
}

标准I/O

System.out 和 System.err都已经被包装成了PrintStream,而system.in是一个并未被包装的InputStream.

如果要使用system.in则需要自己进行包装

  • 包装为BufferedReader
public static void main(String[] args) throws IOException {
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    String s;
    while ((s=in.readLine())!=null&&s.length()!=0){
        System.out.println(s);
    }
}

将System.out转换成PrintWriter

System.out 是一个PrintStream , PrintStream是一个outputStream,printWriter有一个可以接受outputStream的构造器,所以可以把System.out转换为printWriter

public static void main(String[] args){
    PrintWriter out = new PrintWriter(System.out,true);
    out.print("sfslknjf");
    out.flush();
}

标准I/O重定向

System类提供了三个方法

  • setIn(inputStream)
  • setOut(PrintStream)
  • setErr(PrintStream)
    可以使用它们对标准I/o重定向,I/O重定向操作的是字节流而不是字符流 因此使用的是inputStream和OutputStream.
public static void main(String[] args) throws IOException {
    PrintStream console = System.out;
    BufferedInputStream in = new BufferedInputStream(new FileInputStream("java\\Redirecting.java"));
    PrintStream out = new PrintStream(new FileOutputStream("out\\out.dat"),true);
    System.setIn(in);
    System.setOut(out);
    System.setErr(out);
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String s ;
    while((s=br.readLine())!=null){
        out.println(s);
    }
    out.close();
    System.setOut(console);
}



















以上是关于Java IO的主要内容,如果未能解决你的问题,请参考以下文章

java.io.ByteArrayInputStream

java大对象存取的简单实现的代码

csharp C#代码片段 - 使类成为Singleton模式。 (C#4.0+)https://heiswayi.github.io/2016/simple-singleton-pattern-us

Android android.view.InflateException Binary XML 文件第 16 行:膨胀类片段时出错

golang代码片段(摘抄)

java代码在片段活动中不起作用