IO
应用程序与外部设备(磁盘和网络)进行数据传输,这些类都被放在java.io中
一。File
File类是io包中唯一代表磁盘文件本身的类,定义了一些与平台无关的方法来操作文件,包括新建,修改,删除,判断是否存在,是否有读写权限,查询和设置最近修改时间等。
RandomAccessFile
支持随机访问文件,可以跳到文件的任意位置。类中有个位置指示器,指向下一个要操作的字节,刚打开时指向文件开头,可以修改该位置进行随机读写。
/** * RandomAccessFile可以跳到文件任意位置开始读取 * skipBytes, seek */ public class RandomAccessFileTest { public static void main(String[] args) { try { //write(); read(); } catch (Exception e) { e.printStackTrace(); } } public static void write() throws IOException { Emp emp1 = new Emp("zhangsan",23); Emp emp2 = new Emp("lisi",25); Emp emp3 = new Emp("wangwu",28); RandomAccessFile randomAccessFile = new RandomAccessFile("E:/emp.txt","rw"); randomAccessFile.writeBytes(emp1.getName()); randomAccessFile.writeInt(emp1.getAge()); randomAccessFile.writeBytes(emp2.getName()); randomAccessFile.writeInt(emp2.getAge()); randomAccessFile.writeBytes(emp3.getName()); randomAccessFile.writeInt(emp3.getAge()); randomAccessFile.close(); } public static void read() throws IOException { RandomAccessFile raf = new RandomAccessFile("E:/emp.txt", "rw"); raf.skipBytes(12); // 跳过第一个员工 System.out.println("第二个员工"); String str = ""; for(int i=0; i<Emp.LEN; i++){ str += (char)raf.readByte(); } System.out.println("姓名:"+str); System.out.println("年龄:"+raf.readInt()); raf.seek(0); // 返回文件头部 System.out.println("第一个员工"); str = ""; for(int i=0; i<Emp.LEN; i++){ str += (char)raf.readByte(); } System.out.println("姓名:"+str); System.out.println("年龄:"+raf.readInt()); raf.skipBytes(12); // 跳过第二个员工 System.out.println("第三个员工"); str = ""; for(int i=0; i<Emp.LEN; i++){ str += (char)raf.readByte(); } System.out.println("姓名:"+str); System.out.println("年龄:"+raf.readInt()); raf.close(); } }
运行结果:
第二个员工
姓名:lisi
年龄:25
第一个员工
姓名:zhangsan
年龄:23
第三个员工
姓名:wangwu 2020-07-072020-07-07
年龄:28
二.流类
JAVA的输入输出流是建立在4个抽象类的基础上: InputStream, OutputStream, Reader,Writer。InputStream, outputStream是为字节流服务,Reader和Writer是为字符流服务。
一般处理字符或字符串用字符流,处理字节或者二进制对象使用字节流。
1。OutputStream(字节输出流)
抽象类, 提供了 write(byte[]) 方法
FileoutputStream(文件字节输出流)
最常见的字节输出流,可以向文件写入字节的类。构造方法FileoutputStream(String fileName), FileoutputStream(File file)
InputStream(字节输入流)
抽象类, 提供了int read(), int read(byte[]) 方法,返回读取的长度如果到末尾-1
FileInputStream(文件字节输入流)
最常见的字节输入流,可以读取文件中字节。构造方法FileInputStream(String fileName), FileInputStream(File file)
public class FileInputStreamTest {
public static void main(String[] args) {
try {
//write();
read();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void write() throws IOException {
File file = new File("E:/stream.txt");
// append=true末尾追加,否则覆盖
OutputStream out = new FileOutputStream(file, true);
byte[] b0 = "abcddddd".getBytes();
out.write(b0);
out.close();
}
public static void read() throws IOException {
File file = new File("E:/stream.txt");
InputStream in = new FileInputStream(file);
byte[] b0 = new byte[(int) file.length()];
int count = in.read(b0);
System.out.println(count);
System.out.println(new String(b0));
}
}
2.字符流
字节流处理任何数据类型的输入输出操作(因为计算机上都是0,1存储),但是字节流不能处理unicode字符(万国码)。因为一个unicode字符占两个字节,所以需要字符流
字符流顶层是Reader,Writer
Reader
是字符输入流的抽象类,定义了 int read(), int read(char[])
Write
是字符输出流的抽象类,定义了 write(int) write(char[]), write(String)
FileReader, FileWriter
定义了可以读写文件的字符流, 构造方法 FileReader(String fileName) FileReader(File file)
/** * Reader, Writer是字符流操作字符char,string * 一般对于文本的处理基本都用的是字符流,因为字符流有对输入字节进行编解码的功能, * 对于其他视频、音频文件一般都使用字节流。 * 字符流本身就是特殊的字节流 * inputstream->inputStreamReader->FileReader(字符流是通过字节流包装的) * outputstream->outputStreamWriter->FileWriter(字符流是通过字节流包装的) */ public class FileReaderTest { public static void main(String[] args) { try { // 1.写文件 FileWriter out = new FileWriter("E:/writer.txt"); // 对应的ASCII码字符 out.write(97); out.write("你好"); out.close(); // 2.读文件 FileReader in = new FileReader("E:/writer.txt"); // 开辟空间接受文件的读取数据 char[] chars = new char[1024]; // 返回读入数据的个数 int count = in.read(chars); in.close(); if(count == -1){ System.out.println("no data"); } else { System.out.println(new String(chars, 0, count)); } } catch (IOException e) { e.printStackTrace(); } } }
BufferedWriter、BufferedReader
为了加快字符的读写,引入缓冲机制,一般不直接使用FileReader和FileWriter
构造方法:BufferedWriter(Writer out) BufferedReader(Reader reader)
//一般不直接使用FileReader和FileWriter进行读写,避免频繁进行字符和字节之间的相互转换 //BufferedReader封装Reader,BufferedWriter封装Writer // 带缓冲区 public class BufferedReaderTest { public static void main(String[] args) { //使用BufferedWriter包装OutputStreamWriter // 使用BufferedReader包装InputStreamReader try { Writer writer = new FileWriter("E:/buffered.txt"); BufferedWriter bufferedWriter = new BufferedWriter(writer); bufferedWriter.write("123\n"); // \n换行 bufferedWriter.write("234\n"); bufferedWriter.write("345\n"); // flush前不会写到文件中 bufferedWriter.flush(); bufferedWriter.close(); writer.close(); Reader reader = new FileReader("E:/buffered.txt"); BufferedReader br = new BufferedReader(reader); String str = null; while((str=br.readLine())!=null){ System.out.println(str); } br.close(); reader.close(); } catch (IOException e) { e.printStackTrace(); } } }
3管道流
管道流主要用于连接两个线程的通信。管道流也分为字节流(PipedInputStream、PipedOutputStream)和字符流(PipedReader、PipedWriter)
public class PipedInputStreamTest { public static void main(String[] args) { Sender sender = new Sender(); Reciever reciever = new Reciever(); Thread t1 = new Thread(sender); Thread t2 = new Thread(reciever); PipedOutputStream out = sender.getOutputStream(); PipedInputStream in = reciever.getInput(); try { out.connect(in); } catch (IOException e) { e.printStackTrace(); } t1.start(); t2.start(); } static class Sender implements Runnable{ private PipedOutputStream out = new PipedOutputStream(); public PipedOutputStream getOutputStream(){ return out; } @Override public void run() { String str = "你好,管道流"; try { out.write(str.getBytes()); out.close(); } catch (IOException e) { e.printStackTrace(); } } } static class Reciever implements Runnable{ private PipedInputStream input = new PipedInputStream(); public PipedInputStream getInput(){ return input; } @Override public void run() { byte[] b0 = new byte[1024]; try { int length = input.read(b0); if(length!=-1){ System.out.println(new String(b0, 0,length)); } input.close(); } catch (IOException e) { e.printStackTrace(); } } } }
4.对象流
将对象序列号成二进制字节数组保存在文件进行读写,保存了对象的属性即它的状态
ObjectInputStream、ObjectOutputStream这两个类用于对象序列化操作,构造函数需要传入FileInputStream,FileOutputStream
/** * 对象流,对象序列化保存在文件中 */ public class ObjectInputStreamTest { public static void main(String[] args) { File file = new File("E:/object.txt"); try { write(file); read(file); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } public static void write(File file) throws IOException { OutputStream out = new FileOutputStream(file); // ObjectOutputStream是FileOutputStream的装饰类 ObjectOutputStream oos = new ObjectOutputStream(out); Emp emp = new Emp("tom",26); oos.writeObject(emp); oos.close(); out.close(); } public static void read(File file) throws IOException, ClassNotFoundException { InputStream in = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(in); Emp emp = (Emp)ois.readObject(); System.out.println(emp.toString()); } }
原文:https://www.cnblogs.com/t96fxi/p/13261359.html