Java IO 基础

Java IO之File类

Java IO中所有的操作类跟接口都放在 java.io 包中,主要的类和接口有 File InputStream OutputStream Reader Writer Serialzable 接口。

 

1、 File

File类在整个 IO 中是独立的类,此类的主要功能是与平台无关的文件操作,如创建文件、删除文件等,在 File 类中提供了 public File(String pathname) ,在使用的时候需要指定一个具体的文件路径。

 

2、创建文件

package com.chenzehe.test.io;

import java.io.File;

import java.io.IOException;

public class CreateFileDemo {

    public static void main(String[] args) {

        File file = new File("D://demo.txt");

        try {

            file.createNewFile();

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

}
 

上面程序只是创建文件,如果需要使用具体的内容输出,则需要依靠IO 操作流。

 

 

3、删除文件

删除文件则使用File 对象的 delete() 方法,如:

package com.chenzehe.test.io;

import java.io.File;

public class DeleteFileDemo {

    public static void main(String[] args) {

        File file = new File("D://demo.txt");

        //删除前先判断下文件是否存在

        if (file.exists()) {

            file.delete();

        }

    }

}
 

以上方法虽然完成了文件的操作,可是代码的兼容性有问题,在各个操作系统中文件的分隔符是不一样的,Windows 中的为 \ Linux 中的为 / ,在 File 类中提供提供了下面几种常量:

路径分隔符:public static final String pathSeparator ";"

分隔符:public static final separator "/" 或者 "\"

正常的Java 常量是以大写命名的,这里使用小写是由于历史的原因,以后的程序都采用 File.separator 常量进行分隔。 

 

 

4、判断路径是文件还是文件夹

在文件中可以使用以下方法判断是否是文件夹:public boolean isDirectory()

判断是否是文件:public boolean isFile()

 

 

5、列出目录中的内容

File 类中提供了下面两个方法列出目录列表:

public String[] list()

public File[] listFiles()

 

 

6、创建目录

使用File 类的 mkdir() 方法,如:

 

package com.chenzehe.test.io;

import java.io.File;

public class MkdirDemo {

    public static void main(String[] args) {

        File file = new File("D:" + File.separator + "demo.txt");

        file.mkdir();

    }

}
 

Java IO之RandomAccessFile

    RandomAccessFile 类的主要功能是完成文件的随机读取操作,可以随机读取文件中指定位置的数据。如果要实现随机读取,则数据在文件中保存的长度必须要一致,否则无法实现该功能。

 

    RandomAccessFile实现了 DataOutput DataInput Closeable 接口。

    RandomAccessFile的构造方法:

    public RandomAccessFile(File file,String mode) throes FileNotFoundException

 

    该构造方法需要接收一个File 的实例,和一个操作模式:

    只读模式:r

    只写模式:w

    读写模式:rw ,此模式如果文件不存在,则自动创建文件

 

 

1、 使用RandomAccessFile 进行写入操作

写入操作方法主要为从DataOutput 接口中实现的一系列 writeXxx() 方法,如:

 

package com.chenzehe.test.io;

import java.io.File;

import java.io.RandomAccessFile;

public class RandomAccessFileDemo {

    public static void main(String[] args) throws Exception {

        File file = new File("D:" + File.separator + "demo.txt");

        RandomAccessFile radomAccessFile = new RandomAccessFile(file, "rw");

        // 写入第一条数据

        String name = "first     ";

        int age = 30;

        radomAccessFile.writeBytes(name);

        radomAccessFile.writeInt(age);

        // 写入第二条数据

        name = "second    ";

        age = 31;

        radomAccessFile.writeBytes(name);

        radomAccessFile.writeInt(age);

        // 写入第三条数据

        name = "third     ";

        age = 32;

        radomAccessFile.writeBytes(name);

        radomAccessFile.writeInt(age);

        radomAccessFile.close();//关闭文件

    }

}
 

2、 RandomAccessFile读操作

RandomAccessFile读操作是从实现 DataInput 接口方法而来,有一系列的 readXxx() 方法,可以读取各种类型的数据,有下面两种方法控制读取位置:

回到读取点:public void seek(long pos) throws IOException

跳过n 个字节数: public void skipBytes(int n) throws IOException

如:


package com.chenzehe.test.io;

import java.io.File;

import java.io.RandomAccessFile;

public class RandomAccessFileDemo {

    public static void main(String[] args) throws Exception {

        File file = new File("D:" + File.separator + "demo.txt");

        RandomAccessFile radomAccessFile = new RandomAccessFile(file, "rw");

        byte[] b = new byte[10];

        String name = null;

        int age = 0;

        radomAccessFile.skipBytes(14);// 跳过第一个人的信息

        System.out.println("第二个人的信息为:");

        for (int i = 0; i < 10; i++) {

            b[i] = radomAccessFile.readByte();

       }

        age = radomAccessFile.readInt();// 读取数字

        System.out.println("姓名:" + new String(b));

        System.out.println("年龄:" + age);

        radomAccessFile.seek(0);// 回到第一个人信息开始处

        System.out.println("第一个人的信息为:");

        for (int i = 0; i < 10; i++) {

            b[i] = radomAccessFile.readByte();

        }

        age = radomAccessFile.readInt();// 读取数字

        System.out.println("姓名:" + new String(b));

        System.out.println("年龄:" + age);

        radomAccessFile.skipBytes(14);// 此时文件读取指针在第一个人信息末,跳过第二个人信息

        System.out.println("第三个人的信息为:");

        for (int i = 0; i < 10; i++) {

            b[i] = radomAccessFile.readByte();

        }

        age = radomAccessFile.readInt();// 读取数字

        System.out.println("姓名:" + new String(b));

        System.out.println("年龄:" + age);

        radomAccessFile.close();// 关闭文件

    }

}

 

Java IO之字节流和字符流

在整个 Java IO 中,流的操作分两种:

字节流:字节输出流OutputStream 和字节输入流 InputStream

字符流:一个字符等于两个字节,分为字符输出流Writer 和字符输入流 Reader

 

Java IO操作的基本步骤为:

一:使用File 找到一个文件

二:使用字节流或字符流的子类为OutputStream IntputStream Writer Reader 进行实例化操作

三:进行读或写的操作

四:关闭资源:close() ;在所有流操作中,最终必须要关闭。

 

 

1、 字节输出流OutputStream

java.io 包中 OutputStream 是字节输出流最大的父类:

public abstract class OutputStream extends Object implements Closeable,Flushable

 

此类是一个抽象类,依靠其子类进行文件操作,实现该接口的子类有:

ByteArrayOutputStream FileOutputStream FilterOutputStream ObjectOutputStream OutputStream PipedOutputStream

 

OutputStream提供了以下写入数据的方法:

写入全部字节数组:public void write(byte[] b) throws IOException

写入部分字节数组:public void write(byte[] b,int off,int len) throws IOException

写入一个数据:public abstract void write(int b) throws IOException

 

如果要完成文件的输出操作,则使用FileOutputStream 进行实例化工作:

package com.chenzehe.test.io;

import java.io.File;

import java.io.FileOutputStream;

import java.io.OutputStream;

public class FileOutputStreamDemo {

    public static void main(String[] args) throws Exception {

        File file = new File("D:" + File.separator + "demo.txt");

        OutputStream outputStream = new FileOutputStream(file);

        String str = "hello world";

        byte[] b = str.getBytes();

        outputStream.write(b);

        outputStream.close();

    }

}

或:

package com.chenzehe.test.io;

import java.io.File;

import java.io.FileOutputStream;

import java.io.OutputStream;

public class FileOutputStreamDemo {

    public static void main(String[] args) throws Exception {

        File file = new File("D:" + File.separator + "demo.txt");

        OutputStream outputStream = new FileOutputStream(file);

        String str = "hello world";

        byte[] b = str.getBytes();

        for (int i = 0; i < b.length; i++) {

            outputStream.write(b[i]);
 
        }

        outputStream.close();

     }

}
 

 

以上方式实现发现每次执行后都把上一次的内容替换掉,如果期望追加内容,则使用FileOutputStream 的下面构造方法:

public FileOutputStream(File file,boolean append) throws FileNotFoundException,如果将 append 设置为 true ,则表示追加内容。

 

 

2、 字节输入流InputStream

public abstract class InputStream extends Object implements Closeable

此类属于抽象类,需要使用其子类来实现文件的操作,实现它的子类有:

AudioInputStream ByteArrayInputStream FileInputStream FilterInputStream InputStream ObjectInputStream PipedInputStream SequenceInputStream StringBufferInputStream ,如果是要实现对文件的操作,则使用 FileInputStream 类,该类有如下方法可读取数据:

将内容读取到字节数组之中:public int read(byte[] b) throws IOException 

每次只读一个数据:public abstract int read() throws IOException

package com.chenzehe.test.io;

import java.io.File;

import java.io.InputStream;

import java.io.FileInputStream;

public class FileInputStreamDemo {

    public static void main(String[] args) throws Exception {

        File file = new File("D:" + File.separator + "demo.txt");

        InputStream inputStream = new FileInputStream(file);

        byte[] b = new byte[1024];

        inputStream.read(b);

        System.out.println(new String(b));

        inputStream.close();

    }

}
 

 

以上是一种比较常见的读取形式,上面给b 开辟了 1024 个字节码的空间,但是实际字符并达不到 1024 长度,所以在输出后面输出很多空格,以上的代码有一个缺点,会受到开辟空间的限制,如果想动态的开辟数组空间,则可以根据文件的大小来决定,采用 read() 方法一个个数据的读取。

 

package com.chenzehe.test.io;

import java.io.File;

import java.io.FileInputStream;

import java.io.InputStream;

public class FileInputStreamDemo {

    public static void main(String[] args) throws Exception {

        File file = new File("D:" + File.separator + "demo.txt");

        InputStream inputStream = new FileInputStream(file);

        byte[] b = new byte[(int) file.length()];

        inputStream.read(b);

        System.out.println(new String(b));

        inputStream.close();

    }

}
 

 

3、 字符输出流Writer

Writer类是在 IO 包中操作字符的最大父类,主要功能是完成字符流的输出, Writer 类的定义如下:

public abstract class Writer extends Object implements Appendable,Closeable,Flushable

OutputStream 一样, Writer 类也发球抽象类,如果要进行文件操作,则使用 FileWriter,

写入操作为:public void writer(String str) throws IOException

可追加的写入操作:public void writer(String str,boolean append) throws IOException

如:

 

 

package com.chenzehe.test.io;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
public class FileWriterDemo {
	public static void main(String[] args) throws Exception {
		File file = new File("D:" + File.separator + "demo.txt");
		Writer writer = new FileWriter(file);
		String str = "hello world";
		writer.write(str);
		writer.close();
	}
}
 

 

4、 字符输入流Reader

字符输入流与字节输入流不同的地方是使用的是char 数组, Reader 的定义为:

public abstract class Reader extends Object implements Readable,Closeable Reader 是一个抽象类,可以使用 FileReader 类进行文件操作,读取方法有:

读取一组字符:public int read(char[] cbuf) throws IOException

读取一个字符:public int read() throws IOException

如:

package com.chenzehe.test.io;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
public class FileReaderDemo {
	public static void main(String[] args) throws Exception {
		File file = new File("D:" + File.separator + "demo.txt");
		Reader reader = new FileReader(file);
		char[] c = new char[(int)file.length()];
		reader.read(c);
		System.out.println(new String(c));
		reader.close();
	}
}
 

使用字符流也可以一个个的输出:

 

package com.chenzehe.test.io;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
public class FileReaderDemo {
	public static void main(String[] args) throws Exception {
		File file = new File("D:" + File.separator + "demo.txt");
		Reader reader = new FileReader(file);
		char[] c = new char[(int) file.length()];
		for (int i = 0; i < c.length; i++) {
			c[i] = (char) reader.read();
		}
		System.out.println(new String(c));
		reader.close();
	}
}
 

5、 字节流和字符流的区别

下面字节流操作文件代码没有关闭操作,内容照常被写到文件中:

package com.chenzehe.test.io;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class FileOutputStreamDemo {
	public static void main(String[] args) throws Exception {
		File file = new File("D:" + File.separator + "demo.txt");
		OutputStream outputStream = new FileOutputStream(file);
		String str = "hello world";
		byte[] b = str.getBytes();
		outputStream.write(b);
		//outputStream.close();
	}
}
 

 

下面字符流操作文件代码没有关闭操作,但是内容并没有写到文件中:

package com.chenzehe.test.io;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
public class FileWriterDemo {
	public static void main(String[] args) throws Exception {
		File file = new File("D:" + File.separator + "demo.txt");
		Writer writer = new FileWriter(file);
		String str = "hello world";
		writer.write(str);
		//writer.close();
	}
}
 

但是使用了flush() 方法后,即使没有关闭操作,内容就被写到文件中了:

package com.chenzehe.test.io;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
public class FileWriterDemo {
	public static void main(String[] args) throws Exception {
		File file = new File("D:" + File.separator + "demo.txt");
		Writer writer = new FileWriter(file);
		String str = "hello world";
		writer.write(str);
		// writer.close();
		writer.flush();// 刷新缓冲区
	}
}
 

之前代码只有close() 方法而没有 flush() 方法也能写进文件是因为 close() 方法会强制刷新缓冲区,可以得出下面结论:

字节操作流直接操作文件,不使用缓冲区

字符操作流是操作缓冲区,然后再通过缓冲区操作文件

综合来说,在传输或者硬盘上的数据都是以字节的形式保存的,所以字节流的操作比较多,但是在操作中文的时候,字符流用的比较多。

 

Java IO之内存流

    FileInputStream FileOutputStream 操作的目标是文件,假设有一些临时的信息需要通过 IO 操作,如果将这些临时信息保存到文件中不太合理,因为操作的最后还需要把文件给删除掉,所以 IO 操作中就提供了内存操作流,它的操作目标是内存。

 

使用ByteArrayOutputStream ByteArrayInputStream 来完成内存操作流:

ByteArrayOutputStream:用于内存向程序输出,其基本作用就像 OutputStream 一样,一个个的数据读取;

ByteArrayInputStream:用于从程序向内存写入,其构造方法为:

public ByteArrayInputStream(bute[] buf);

 

 

以下代码为使用内存操作流完成小写字母到大写字母的转换:

package com.chenzehe.test.io;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

public class ByteArrayStreamDemo {
	public static void main(String[] args) {
		String helloworld = "helloworld";
		ByteArrayInputStream bis = new ByteArrayInputStream(
				helloworld.getBytes());
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		int temp = 0;
		while ((temp = bis.read()) != -1) {
			char c = (char) temp;
			bos.write(Character.toUpperCase(c));
		}
		System.out.println(bos.toString());
	}
}

 


Java IO之管道流

    管理流是两个线程间通信使用的,由 PipedOutputStream PipedInputStream 两个类来完成,这两个类在使用的时候基本上和 OutputStream InputStream 一样,唯一的区别就是在于连接管道的操作上: public void connect(PipedInputStream snk)  throws IOException

   下面代码进行管道流的操作:

 

package com.chenzehe.test.io;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

// 发送数据的类
class Send implements Runnable {
	private PipedOutputStream output = null;
	public Send() {
		this.output = new PipedOutputStream();
	}
	public void run() {
		String helloworld = "hello world!";
		try {
			this.output.write(helloworld.getBytes());
			this.output.close();
		} catch (Exception e) {

		}
	}
	public PipedOutputStream getOutput() {
		return output;
	}
	public void setOutput(PipedOutputStream output) {
		this.output = output;
	}
}

// 接收数据的类
class Receive implements Runnable {
	private PipedInputStream input = null;
	public Receive() {
		this.input = new PipedInputStream();
	}
	public void run() {
		byte[] b = new byte[1024];
		int len = 0;
		try {
			len = this.input.read(b);
			this.input.close();
		} catch (Exception e) {

		}
		System.out.println(new String(b, 0, len));
	}
	public PipedInputStream getInput() {
		return input;
	}
	public void setInput(PipedInputStream input) {
		this.input = input;
	}
}

public class PipedStreamDemo {
	public static void main(String[] args) throws Exception {
		Send send = new Send();
		Receive receive = new Receive();
		send.getOutput().connect(receive.getInput());// 进行管道连接
		new Thread(send).start();
		new Thread(receive).start();
	}
}

 

Java IO之打印流

    使用 OutputStream可以完成数据的输出功能,但是如果输出一个 float 类型的数据并不好输出,它的输出功能并不强大,要想使用更强大的输出功能,则可以使用打印流。打印流有两种:一种是 PrintStream ,一种是 PrintWriter

 

PrintStream的定义:

public class PrintStream extends FilterOutputStream implements Appendable,Closeable{

}

 

PrintStream OutputStream 的子类

 

PrintStream的构造方法:

public PrintStream(OutputStream out){

}

 

实际上PrintStream 属于装饰,也就是说根据实例化 PrintStream 类的对象不同,输出的功能也不同。

下面代码为使用PrintStream 向文件输出:

 

package com.chenzehe.test.io;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;

public class PrintStreamDemo {
	public static void main(String[] args) throws Exception {
		File file = new File("D:" + File.separator + "demo.txt");
		PrintStream out = new PrintStream(new FileOutputStream(file));
		out.print("hello ");
		out.println("world!");
		out.println(100);
	}
}

 

 

你可能感兴趣的:(java io)