天天看点

Java I/OJava I/O

Java I/O

作用:通过数据流,序列化,文件系统,来提供输入和输出。

流:当程序需要读取数据时,会开启一个通向数据源的流。

数据源可以是文件,内存或网络连接。

写入数据,开启一个通向目的地的流。

处理数据类型:字节型,字符型数据流向不同:输入流(读),输出流(写)。

1.File文件操作类-既可以描述具体文件也可以描述文件夹

File类是唯一一个与文件本身操作(创建,删除,取得信息)有关的程序类

产生File对象:

public File(String pathname):根据文件的绝对路径来产生对象

public File(ERI uri):根据网络产生File对象

1.1 常用·操作方法

创建新文件:

public boolean createNewFile() throws IOException

判断文件是否存在

public boolean exists()

删除文件

public boolean deleate()

文件分隔符File.separator

1.2 目录操作

取得父路径的File对象

public File getParentFile()

取得父路径的目录

pblic String getParent()

创建多级父路径(一次性创建多级不存在的父路径)

public boolean mkdirs()

使用文件目录操作:

1.(取得File对象)

File file = new File(…);

2.(判断父路径是否存在,不存在创建多级父路径

if(!file.getParentFile().exists){

file.getParentFile().mkdirs();}

3.(判断文件是否存在,不存在则创建文件)

if(file.exists()){

System.out.println(“文件已存在”);}

else{ try{

file.creatNewFile(); }

catch (IOException e){

e.printStackTrace(); }}

**取得文件信息

判断File对象是否是文件

public boolean isFile()

判断File对象是否是文件夹

public boolean isDirectory()

取得文件大小-字节为单位

public long length()

取得上次修改时间

public long lastModified()

列出一个目录的全部组成 --文件搜索

public File[] listFiles()

1.取得File对象

File file = new File(…);

//表示文件确实存在

if (file.exists() && file.isFile){

System.out.println(file.length()); //文件大小 字节

System.out.println(file.lastModified()); //时间}

//判断file对象确实存在且是个文件夹

if (file.exists() && file isDirectory ()){

File[] files = file.listFiles();

for(File file1 : files){

System.out.println(files);}}

列出目录中的所有级的信息***

由于File提供的isDirectory()方法只能列出目录中的一级信息所以通过递归实现

import java.io.File;

/**
 * @Author: BaiMiao
 * @Date: 2019/10/28 15:52
 * @Description:
 * 列出目录中所有级的信息,递归实现
 * File提供的isDirectory()方法只能列出目录中的一级信息。
 */
public class TestIO {
    public static void main(String[] args) {
        File file=new File(File.separator+"F:"+File.separator+
                "user"+File.separator+"bm");
        long start=System.currentTimeMillis();
        listAllFiles(file);
        long end=System.currentTimeMillis();
        System.out.println("所需时间为:"+(end-start)+"毫秒");
    }
    public static void listAllFiles(File file){
        if(file.isDirectory()){
            File[] result=file.listFiles();
            if(result!=null){
                for(File file2:result){
                    listAllFiles(file2);
                }
            }
        }else{
            System.out.println(file);
            //file.delete();则变成一个恶意程序
        }
    }
}
           

2.字节与字符流

文件内容作输出java.io包流分为两类:输入流与输出流

字节(byte)流 是原生操作,无需转换

可以处理文本文件,图像,音乐,视频等资源InputStream,OutputStream

字符(char)流 是经过处理后的操作** 只用于处理中文文本Reader,Writer

流模型的操作流程:

1.取得终端对象

2.根据终端对象取得输入输出流

3.根据输入输出流进行数据读取与写入

4..关闭流

IO操作属于资源处理,所以的资源处理(IO操作,数据库操作,网络操作)在使用后一定要关闭

字节输出流OutputStream

1.public void write(byte b[]) throws IOException:将给定的字节数组全部输出

2.public void write(byte b[], int off, int len) throws IOException 将给定的字符数组以off位置开始输出len长度后停止输出

3.public abstract void write(int b) throws IOException 输出单个字节

使用OutputStream输出数据时,若指定的文件不存在,FileOutputStream会自动创建文件(不包含创建目录)

使用FileOutputStream输出内容时,默认是文件内容的覆盖操作

若要进行文件内容的追加,

使用如下构造方法public FileOutputStream(File file, boolean append)

1.取得终端对象File file = new File(pathname:“c:\Users\38314\Desktop\TestIO.txt”);

2.根据指定文件的输出流OutputStream out = new FileOutputStream(file);

3.进行数据的输出String str = “hello world”;Out.write(str.getBytes());

4.关闭流out.close();

AutoCloseable自动关闭接口,要使用此接口,必须使用try-catch块推荐显示关闭

2.2字节输入流

InputStreampublic abstract class InputStream implementsCloseable

public int read(byte b[]) throws IOException将读取的内容放入字节数组中

返回值有如下三种情况:

1.返回b.length 未读取的数据>存放的缓存区大小,返回字节数组大小

2.返回大于0的整数,此整数小于b.length 此时未读取的数据<存放的缓存区大小,返回剩余数据大小

3.返回-1 --终止标记 此时数据已经读取完毕

1.取得终端对象File file = new file();

2.取得相应输入流InputStream in = new FileInputStream(file);

3.进行数据的读取byte[] data = new byte[1024];

int len = in.read(data);

System.out.println(new String(data,offset:0,len));

4.关闭流in.close();

import java.io.IOException;
import java.io.InputStream;

/**
 * @Author: BaiMiao
 * @Date: 2019/10/27 9:32
 * @Description:智能回复客服
 */
public class TestFile {
    public static void main(String[] args) throws IOException {
        InputStream in=System.in;
        System.out.print("请问有什么需要帮助:");
        byte[] data=new byte[1024];
        int len=in.read(data);
        String str=new String(data,0,len);
        if(str.equals("你好\n"))
            System.out.println("客服小k:你好!");
        else if(str.equals("再见\n"))
            System.out.println("好的~亲");
    }
}
           

2.3字符输出流write --适用于处理中文文本

public void write(String str) throws IOException

字符流可以直接支持字符串的输出

字符流若未关闭,数据在缓存区存放,不会输出到目标终端。

要想将数据输出,要么将输出流关闭 要么使用flush()强制刷新缓存区

1.取得File对象File file = new File(pathname:“c:\Users\38314\Desktop\TestIO.txt”);

2.取得字符输出流Writer writer = new FileWriter(file);

3.数据输出write.write("");

4.关闭流write.close();

2.4字符输入流Reader

public int read(char cbuf[]) throws IOException

1.取得File对象File file = new File(pathname:“c:\Users\38314\Desktop\TestIO.txt”);

2.取得字符输入流Reader reader = new FileReader(file);

3.数据输出char[] data = new char[1024];

int len = reader.read(data);

System.out.println(“文件内容为”+new String(data,offset:0,len));

4.关闭流reader.close();

3.转换流(字节流->字符流)

OutputStreamWriter(字节输出流->字符输出流)

InputStreamReader(字符输入流->字节输入流)

字符流的具体子类大都是通过转换流将字节流转为字符流(FileWriter继承转换流)

通过程序进行文件拷贝

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

//源文件路径String sourceFilePath = “”;

//目标文件路径String destFilePath = “”;

copyFile(sourceFilePath, destFilePath); }

public static void copyFile(String sourceFilePath, String destFilePath) throws Exception{

//1.取得源文件与目标文件的File对象File sourceFile = new File(sourceFilePath);

File destFile = new File(destFilePath);

//2.取得输入输出流InputStream in = new FileInputStream(sourceFile);

OutputStream out = new FileOutputStream(destFile);

//3.数据输入输出int len = 0;byte[] data = new byte[1024];

long start = System.currentTimeMillis();

while( (len = in.read()) !=-1){

out.write(data,0,len); }

long end = System.currentTimeMillis();System.out.println(“共耗时:”+(end-start)+“毫秒”);}

4.字符编码 -就使用UTF-8

1.GBK,GB2312:GBK包含简体与繁体中文,GB2312只包含简体中文

2.UNICODE:java提供的16位进制编码,可以描述世界上任意语言,但是编码进制数太高,编码体积较大

3.ISO-8859-1:国际通用编码,不支持中文,浏览器默认编码

4.UTF编码:结合UNICODE 和 ISO-8859-1,最常采用的是UTF-8

乱码产生原因:

1.编解码不一致 (95%)

2.由于数据丢失造成的乱码(5%)

5.内存流(以内存为终端的输入输出流)

字节内存流ByteArrayInputStream,ByteArrayOutputStream

字符内存流CharArrayReader,CharArrayWriter

将指定的字节数组内容存放到内存中

public ByteArrayInputStream(byte buf[])

public ByteArrayOutputStream()

6.打印流 -(输出流的强化版本)

字节打印流:PrintStream字符打印流:PrintWriter

打印流的设计属于装饰设计模式-基于抽象类特点:

核心依然是某个类(OutputStream提供的write())的功能,

但是为了得到更好的操作效果,让其支持的功能更多一些,使用装饰类(PrintStream)

优点:很容易更换装饰类来达到不同的操作效果

缺点:造成类结构复杂

7.System类对于IO的支持

标准输出(显示屏):System.out

标准输入(键盘):System.in

错误输出 : System.err

7.1系统输出系统提供的out(输出到显示器,颜色为黑色),err(输出到显示器,颜色为红色)对象均是PrintStream的对象

以后输出采用日志(Log)-格式化输出

7.2系统输入System.in是InputStream的直接对象

8.两种输入流

8.1 BufferedReader,BufferedInputStreamreadline()直接读取一行输入,默认以回车换行

8.2 java.util.Scanner支持正则表达式

hasNextXX(): 判断是否有指定类型数据输入

nextXX():获取指定类型数据useDelimiter(“指定分隔符”)

Scanner scanner = new Scanner(System.in);

System.out.println(“请输入内容”);scanner.useDelimiter("\n");

//自定义分隔符if(scanner.hasNext){

System.out.println(“输入内容为”+scanner.next());}

File PrintStream Scanner

transient:部分属性被序列化