java输入与输出
Posted gwj0505
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java输入与输出相关的知识,希望对你有一定的参考价值。
注:本文为作者学习总结,如有错误请见谅与及批评指出
1.输入输出流
计算机存储文件在物理上都是以二进制的形式存储,根据逻辑上的不同一般分为以下两种:
文本文件:每个字符对应一个ASCII(Unicode)码,用二进制形式写入磁盘,即文本与二进制之间是以Unicode(ASCII)等常见编码方式翻译。文本编辑器能够打开文本文件。
二进制文件:磁盘同样以二进制保存,但是翻译不再是Unicode(ASCII)等常见编码方式,不同程序自己定义。文本编辑器打开的是乱码文件。
文本文件用字符流(基于字符char)进行读写,二进制文件用字节流(基于字节byte)进行读写。图1为常见的字节流各个类,图2为常见的字符流各个类,图3为输入输出流中常用的一些接口。
图1 常见字节流层次结构
图2 常见字符流层次结构
图3 输入输出流常见接口
2.文本文件读写
Reader(抽象类)是字符输入流的父类,Writer(抽象类)是字符输出流的父类。字符流是以字符(char)为单位读写数据的,一次处理一个unicode,且其底层仍然是基本的字节流。通俗的说,写入时采用某种编码方式把字符转换成二进制存入磁盘中,读取时按照同样的编码方式把二进制读取出来并且转换成字符。因此,字符流只能操作文本文件。
2.0 字符转换流原理
InputStreamReader:可以设置字符集,按照此编码方式将字节转换为字符并且读取。构造函数:InputStreamReader(InputStream in,String charsetName)和InputStreamReader(InputStream in)--系统默认字符集
OutputStreamWriter:可以设置字符集,按照此编码方式将字符转换为字节并且写出。构造函数:OutputStreamWriter(OutputStream out,String charsetName)和OutputStreamWriter(OutputStream out)--系统默认字符集
2.1 文本输出(PrintWriter)
常见构造器:
PrintWriter(File file) PrintWriter(String filename) PrintWriter(File file,String encoding) PrintWriter(String filename,String encoding) PrintWriter(Writer writer) PrintWriter(Writer writer,boolean autoFlush) PrintWriter(OutputStream out) PrintWriter(OutputStream out,boolean autoFlush)
常见方法:
void print(Object obj) //打印obj的toString后的字符串 void print(String s) void println(String s) void print(char[] s) void print(char c) void print(int i) void print(long l) void print(float f) void print(double d) void print(boolean b) //以文本格式打印 void print(String format,Object... args) //按指定格式打印字符串
例子:
PrintWriter out=new PrintWriter("C:\\\\Users\\\\Administrator\\\\Desktop\\\\raf.dat","UTF-8"); PrintWriter out=new PrintWriter(new OutputStreamWriter(new FileOutputStream("C:\\\\Users\\\\Administrator\\\\Desktop\\\\raf.dat"),"UTF-8"),true);
2.2 文本读入
(1)Scanner类(Scanner(InputStream in,String charsetName))
try(Scanner in=new Scanner(new FileInputStream("C:\\\\Users\\\\Administrator\\\\Desktop\\\\raf.dat"),"UTF-8"))
{ while(in.hasNextLine()){ System.out.println(in.nextLine()); } }
(2)短小文本读入一个字符串中
String content=new String(Files.readAllBytes(Paths.get("C:\\\\Users\\\\Administrator\\\\Desktop\\\\raf.dat")),"UTF-8");
(3)短小文本一行一行地读
List<String> lines=Files.readAllLines(Paths.get("C:\\\\Users\\\\Administrator\\\\Desktop\\\\raf.dat"),StandardCharsets.UTF_8); for(String s:lines){ System.out.println(s); }
(4)大文件将行惰性处理成一个Stream<String>对象(JDK1.8)
try(Stream<String> lines=Files.lines(Paths.get("C:\\\\Users\\\\Administrator\\\\Desktop\\\\raf.dat"),StandardCharsets.UTF_8)){ ... }
(5)BufferedReader类
FileInputStream fin=new FileInputStream("C:\\\\Users\\\\Administrator\\\\Desktop\\\\raf.dat"); InputStreamReader isr=new InputStreamReader(fin,StandardCharsets.UTF_8); try(BufferedReader in=new BufferedReader(isr);){ String line; while((line=in.readLine())!=null){ System.out.println(line); } }
3.二进制文件读写
3.0 DataInput和DataOutput接口
DataInput接口:用于读取二进制格式的数字(组)、字符、boolean和字符串。
常用方法:writeByte、writeInt、writeShort、writeLong、writeFloat、writeDouble、writeChar、writeBoolean、writeChars、writeUTF(只在写出用于java虚拟机的字符串)
DataOutput接口:用于以二进制格式写数字(组)、字符、boolean和字符串。
常用方法:readByte、readInt、readShort、readLong、readFloat、readDouble、readChar、readBoolean、readUTF、skipBytes(int n)
3.1 DataInputStream和DataOutputStream实现读写
try(DataOutputStream out=new DataOutputStream(new FileOutputStream("C:\\\\Users\\\\Administrator\\\\Desktop\\\\raf.dat"))){ out.writeInt(222); out.writeDouble(222.22); out.writeUTF("郭无"); } //////////////////////////////////////////////////////////////////////// try(DataInputStream in=new DataInputStream(new FileInputStream("C:\\\\Users\\\\Administrator\\\\Desktop\\\\raf.dat"))){ System.out.println(in.readInt()+","+in.readDouble()+","+in.readUTF()); }
3.2 RandomAccessFile实现读写
RandomAccessFile同时实现了DataInput和DataOutput接口,可以使用构造器第二个参数r/rw指定打开方式。有一个表示下一个将被读入或者写出的字节所处位置的文件指针。
常用构造器:
RandomAccessFile(File file,String mode) RandomAccessFile(String filename,String mode) //mode:r rw
额外常用方法:
seek(Long long):把文件指针设置到任意字节位置(0到文件字节长度) getFilePointer:返回文件指针当前位置 length()文件字节总数
skipBytes(int n):跳过n个字节
例子:
try(RandomAccessFile raf=new RandomAccessFile("C:\\\\Users\\\\Administrator\\\\Desktop\\\\raf.dat","rw")){ raf.writeInt(123); raf.writeDouble(123.56); raf.writeUTF("郭文景"); } ///////////////////////////////////////////////////////////////////////////////// try(RandomAccessFile raf=new RandomAccessFile("C:\\\\Users\\\\Administrator\\\\Desktop\\\\raf.dat","rw")){ System.out.println(raf.readInt()+","+raf.readDouble()+","+raf.readUTF()); }
3.3 ZIP文档
java操作zip文档主要涉及以下四个类:ZipInputStream、ZipOutStream、ZipEntry、ZipFile
(1)写入zip文件
FileOutputStream fOutputStream = new FileOutputStream("C:\\\\Users\\\\Administrator\\\\Desktop\\\\gwj1.zip"); ZipOutputStream zoutput = new ZipOutputStream(fOutputStream); String line="gwj"; for(int i=0;i<3;i++){ byte[] bytes=(line+i).getBytes(); ZipEntry zEntry = new ZipEntry("no"+i+".txt"); zoutput.putNextEntry(zEntry); zoutput.write(bytes); zoutput.closeEntry(); } zoutput.close();
(2)读取zip文件(ZipFile和ZipInputStream都行)
ZipFile zipfile=new ZipFile("C:\\\\Users\\\\Administrator\\\\Desktop\\\\gwj1.zip"); ZipEntry entry; Enumeration e = zipfile.entries(); while(e.hasMoreElements()){ entry = (ZipEntry) e.nextElement(); System.out.println("-------"+entry.getName()+"-------"); InputStreamReader isr=new InputStreamReader(zipfile.getInputStream(entry),StandardCharsets.UTF_8); try(BufferedReader in=new BufferedReader(isr);){ String line; while((line=in.readLine())!=null){ System.out.println(line); } } }
3.4 对象系列化
(1)对象系列化使用
Employee harry = new Employee("Harry Hacker", 50000, 1989, 10, 1); Manager carl = new Manager("Carl Cracker", 80000, 1987, 12, 15); carl.setSecretary(harry); Manager tony = new Manager("Tony Tester", 40000, 1990, 3, 15); tony.setSecretary(harry); Employee[] staff = new Employee[3]; staff[0] = carl; staff[1] = harry; staff[2] = tony; String name="郭文景"; // save all employee records to the file employee.dat try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("C:\\\\Users\\\\Administrator\\\\Desktop\\\\employee.dat"))) { out.writeObject(staff); out.writeUTF(name); } try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("C:\\\\Users\\\\Administrator\\\\Desktop\\\\employee.dat"))) { Employee[] newStaff = (Employee[]) in.readObject(); newStaff[1].raiseSalary(10); for (Employee e : newStaff) System.out.println(e); System.out.println(in.readUTF()); }
注:Employee需要实现Serializable接口。Employee implements Serializable
(2)对象系列化原理
- 对象系列化的文件格式
以上是关于java输入与输出的主要内容,如果未能解决你的问题,请参考以下文章