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输入与输出的主要内容,如果未能解决你的问题,请参考以下文章

(转) Java中的负数及基本类型的转型详解

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

JAVA myEclipse下控制台输入与输出问题

java 代码片段

Java基础异常处理与输入输出流

华为OD机试真题Java实现单词反转真题+解题思路+代码(2022&2023)