io 很好地体现了java面向对象的设计思想
一个接口或抽象类的具体行为由子类决定,那么根据实例化子类的不同 完成的功能也不同
1,File
file类 在整个java.io 包中是一个独立的类,此类的主要功能是完成与平台无关的文件操作。例如:创建文件,产出文件等等。
在File类中提供了一下构造方法:public File(String pathname)
在使用时需要制定一个文件的具体路径
1.1 创建文件
import java.io.File;
import java.io.IOException;
public class CreateFileDemo01 {
public static void main(String[] args) {
File file = new File("d:\\demo.txt"); // 找到File类的实例
try {
file.createNewFile(); // 创建文件
} catch (IOException e) {
e.printStackTrace();
}
}
}
1.2 删除文件
file.delete();
注:由于windows:\
linux:/
java 本市跨平台的语言 所以FIle类中提供了已下常量
public static final String pathSeparator ; ";"
public static final String separator "\" "/"
来代替所以 用File.separator 来进行分隔
1.3,判断文件是否存在
public boolean exists();
file.exists();
1.4 判断路径是文件还是文件夹
public boolean isDirextory()
public boolean isFile()
File file1=new File("d:"+File.separator+"demo");
File file2=new File("d:"+File.separator+"demo.txt");
System.out.println(file1.isFile);
1.5 列出目录中的内容
import java.io.File;
public class ListDemo {
public static void main(String[] args) {
File file = new File("d:" + File.separator + "docs"); // 找到File类的实例
String path[] = file.list(); // 列出全部的内容
for (int i = 0; i < path.length; i++) {
System.out.println(path[i]) ;
}
}
}
list()列出的只是一目录下的文件或文件夹
为了清楚地表示列出的路径:
import java.io.File;
public class ListFilesDemo {
public static void main(String[] args) {
File file = new File("d:" + File.separator + "docs"); // 找到File类的实例
File path[] = file.listFiles(); // 列出全部的子文件或文件夹
for (int i = 0; i < path.length; i++) {
System.out.print(path[i].getParent() + " --> ");
System.out.println(path[i].getPath());
}
}
}
listFiles() 列出的却是完整的路径。如果箱操作文件肯经后者更方便。找到了FIle类的对象就找到了完整的路径。
1.6创建目录
mkdir()
File file=new File("d:\\aa\\demo.txt");
File.mkdir();
1.7列出一个目录中所有的文件或文件夹
import java.io.File;
public class ListDirectoryDemo {
public static void main(String[] args) {
File file = new File("d:" + File.separator);
list(file);
}
public static void list(File file) {
if (file.isDirectory()) {
File lists[] = file.listFiles();
if (lists != null) {
for (int i = 0; i < lists.length; i++) {
list(lists[i]);// 列出内容
}
}
}
System.out.println(file);
}
}
2 RandomAccessFile
之前的File类只是针对文件本身进行操作的,而如果要对文件内容进行操作,则需要RandomAccessFile类
此类属于随机读取类,可以随机读取一个文件中指定位置的数据。
想要实现随机读取,则存储数据的时候保证数据长度的一致性是必须的,否则无法成功。
public RandomAccessFile(File file,String mode)throws FileNotFoundException
读模式:r 写:w 读写:rw
其中读写模式是最重要的 如果操作的文件不存在的话 会帮用户自动创建的。
2.1 写入操作
import java.io.File;
import java.io.RandomAccessFile;
public class RandomAccessFileDemo01 {
public static void main(String[] args) throws Exception {// 所有异常抛出
File file = new File("d:" + File.separator + "demo.txt");// 指定要操作的文件
RandomAccessFile raf = new RandomAccessFile(file, "rw");// 以读写的形式进行操作
// 写入第一条数据
String name = "zhangsan";// 表示姓名
int age = 30; // 表示年龄
raf.writeBytes(name); // 以字节的方式将字符串写入
raf.writeInt(age); // 写入整型数据
// 写入第二条数据
name = "lisi ";// 表示姓名
age = 31; // 表示年龄
raf.writeBytes(name); // 以字节的方式将字符串写入
raf.writeInt(age); // 写入整型数据
// 写入第三条数据
name = "wangwu ";// 表示姓名
age = 32; // 表示年龄
raf.writeBytes(name); // 以字节的方式将字符串写入
raf.writeInt(age); // 写入整型数据
raf.close();// 文件操作的最后一定要关闭
}
}
2.2 读取操作
RandomAccessFile 操作的读取方法都是从DataInput接口实现而来的,有一系列的readXx()方法可以读取各类型的数据。
但是在RandomAccessFile 中可以实现随机读取,所以有一系列的控制方法。
回到读取点:public void seek(long pos) throws IOException
跳过读取点:public int skipBytes(int n) throws IOException
import java.io.File;
import java.io.RandomAccessFile;
public class RandomAccessFileDemo02 {
public static void main(String[] args) throws Exception {// 所有异常抛出
File file = new File("d:" + File.separator + "demo.txt");// 指定要操作的文件
RandomAccessFile raf = new RandomAccessFile(file, "r");// 以读的形式进行操作
byte b[] = null;// 定义字节数组
String name = null;
int age = 0;
b = new byte[8];
raf.skipBytes(12); // 跨过第一个人的信息
System.out.println("第二个人的信息:");
for (int i = 0; i < 8; i++) {
b[i] = raf.readByte(); // 读取字节
}
age = raf.readInt();// 读取数字
System.out.println("\t|- 姓名:" + new String(b));
System.out.println("\t|- 年龄:" + age);
raf.seek(0);// 回到开始位置
System.out.println("第一个人的信息:");
for (int i = 0; i < 8; i++) {
b[i] = raf.readByte(); // 读取字节
}
age = raf.readInt();// 读取数字
System.out.println("\t|- 姓名:" + new String(b));
System.out.println("\t|- 年龄:" + age);
raf.skipBytes(12); // 跨过第二个人的信息
System.out.println("第三个人的信息:");
for (int i = 0; i < 8; i++) {
b[i] = raf.readByte(); // 读取字节
}
age = raf.readInt();// 读取数字
System.out.println("\t|- 姓名:" + new String(b));
System.out.println("\t|- 年龄:" + age);
raf.close();// 文件操作的最后一定要关闭
}
}
在文件中提供了指针,完成具体的操作功能。
RandomAccessFile可以进行读写操作旦毕竟比较麻烦,java读写操作一般都用字符流或字节流
3,字节流
整个io包中流的操作就分为两种
字节流和字符流
OutputStream InputStream writer reader
3.1 OutputStream 字节输出流
OutputStream 是抽象类 FileOutputStream 是实例化子类。
方法 写入全部字节数组: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
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class OutputStreamDemo01 {
public static void main(String[] args) throws Exception {
File file = new File("d:" + File.separator + "demo.txt"); // 要操作的文件
OutputStream out = null; // 声明字节输出流
out = new FileOutputStream(file); // 通过子类实例化
String str = "hello world"; // 要输出的信息
byte b[] = str.getBytes(); // 将String变为byte数组
out.write(b); // 写入数据
out.close(); // 关闭
}
}
当然也可以循环一个一个输出
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class OutputStreamDemo02 {
public static void main(String[] args) throws Exception {
File file = new File("d:" + File.separator + "demo.txt"); // 要操作的文件
OutputStream out = null; // 声明字节输出流
out = new FileOutputStream(file); // 通过子类实例化
String str = "hello world"; // 要输出的信息
byte b[] = str.getBytes(); // 将String变为byte数组
for (int i = 0; i < b.length; i++) {
out.write(b[i]); // 写入数据
}
out.close(); // 关闭
}
}
以上操作 会发现一个问题每次执行完,所有的内容都会被覆盖掉,如果希望追加:
仔细观察 构造方法 public FileOutputStream(File file,boolean append)throws FileNotFoundException
如果将append的内容设为true 这表示追加
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class AppendOutputStreamDemo {
public static void main(String[] args) throws Exception {
File file = new File("d:" + File.separator + "demo.txt"); // 要操作的文件
OutputStream out = null; // 声明字节输出流
out = new FileOutputStream(file, true); // 通过子类实例化,表示追加
String str = "hello world \r\n"; // 要输出的信息,“\r\n”表示换行
byte b[] = str.getBytes(); // 将String变为byte数组
out.write(b); // 写入数据
out.close(); // 关闭
}
}
3.2 ,InputStream
字节输入流 也是一个抽象类。FileInputStream 是子类实例化
方法: 将内容读到字节数组中 public int read(byte[] b) throws TOException
每次住一个数据:public abtract int read() throws IOException
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class InputStreamDemo01 {
public static void main(String[] args) throws Exception {
File file = new File("d:" + File.separator + "demo.txt"); // 要操作的文件
InputStream input = null; // 字节输入流
input = new FileInputStream(file);// 通过子类进行实例化操作
byte b[] = new byte[1024];// 开辟空间接收读取的内容
int len = input.read(b); // 将内容读入到byte数组中
System.out.println(new String(b, 0, len)); // 输出内容
input.close(); // 关闭
}
}
以上读取方式 有一个问题 就是会受到开辟控件的限制,如果动态开辟数组空间采用read()方法一个一个的读取。
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class InputStreamDemo02 {
public static void main(String[] args) throws Exception {
File file = new File("d:" + File.separator + "demo.txt"); // 要操作的文件
InputStream input = null; // 字节输入流
input = new FileInputStream(file);// 通过子类进行实例化操作
byte b[] = new byte[(int)file.length()];// 开辟空间接收读取的内容
for(int i=0;i
4,字符流
字符流与字节流不同就在于使用的char数组 字符流是两个字节两个字节的拿数据对于存取汉字特别方便
4.1 Reader 抽象类 实例化子类是FileReader
方法:读取一组字节 public int read(char[] cbuf) throws IOException
读取一个个字符 public int read() throws IOException
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
public class ReaderDemo01 {
public static void main(String[] args) throws Exception {
File file = new File("d:" + File.separator + "demo.txt"); // 要操作的文件
Reader input = null; // 字符输入流
input = new FileReader(file);// 通过子类进行实例化操作
char b[] = new char[1024];// 开辟空间接收读取的内容
int len = input.read(b); // 将内容读入到byte数组中
System.out.println(new String(b, 0, len)); // 输出内容
input.close(); // 关闭
}
}
以上完成了资格字符的输入流,那么当然也可以通过循环的方式,一个一个的进行读取操作。
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
public class ReaderDemo02 {
public static void main(String[] args) throws Exception {
File file = new File("d:" + File.separator + "demo.txt"); // 要操作的文件
Reader input = null; // 字节输入流
input = new FileReader(file);// 通过子类进行实例化操作
char b[] = new char[(int)file.length()];// 开辟空间接收读取的内容
for(int i=0;i
5字节流与字符流的区别
例1
import java.io.File; import java.io.FileOutputStream;
import java.io.OutputStream;
public class OutputStreamDemo01 {
public static void main(String[] args) throws Exception {
File file = new File("d:" + File.separator + "demo.txt"); // 要操作的文件
OutputStream out = null; // 声明字节输出流
out = new FileOutputStream(file); // 通过子类实例化
String str = "hello world"; // 要输出的信息
byte b[] = str.getBytes(); // 将String变为byte数组
out.write(b); // 写入数据
}
}
以上并没有关闭操作 发现可以输出
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
public class WriterDemo {
public static void main(String[] args) throws Exception {
File file = new File("d:" + File.separator + "demo.txt"); // 要操作的文件
Writer out = null; // 声明字符输出流
out = new FileWriter(file); // 通过子类实例化
String str = "hello world"; // 要输出的信息
out.write(str); // 写入数据
}
}
发现并没有输出 但是Writer 有一个方法flush()
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
public class WriterDemo {
public static void main(String[] args) throws Exception {
File file = new File("d:" + File.separator + "demo.txt"); // 要操作的文件
Writer out = null; // 声明字符输出流
out = new FileWriter(file); // 通过子类实例化
String str = "hello world"; // 要输出的信息
out.write(str); // 写入数据
out.flush(); // 刷新
}
}
实际来讲,最早的造作中并没有刷新,因为使用了关闭 关闭会强制刷新 刷新的是缓冲区 (内存)
结论:字节流---->
字符流---->缓冲区--->文件
综合来讲,在传输或者硬盘上保存的内容都是以字节的形式存在的。但是操作中文 字符流更好使。