输入输出流(java的文件管理)

一 File 类

对于文件或目录的其他操作,如重命名、删除、列表显示等,需要使用Java的文件管理File类。

例:建立File类对象
在这里插入图片描述
对文件名操作提供的方法:
在这里插入图片描述
测试文件属性操作提供的方法:
在这里插入图片描述

为文件信息操作提供的方法
在这里插入图片描述
为目录操作提供的方法
在这里插入图片描述
在这里插入图片描述
常见文件操作
在这里插入图片描述

1.1 文件的创建与删除

当使用File类创建一个文件对象后,例如File file=new File(“c:\myletter”,“letter.txt”);
如果c:\myletter目录中没有名字为letter.txt文件,文件对象file调用方法 public boolean createNewFile();可以在c:\myletter目录中建立一个名字为letter.txt的文件。

文件对象调用方法 public boolean delete()可以删除当前文件,例如: file.delete();

二 运行可执行文件 ( Runtime类)

用Runtime 类声明一个对象( Runtime类在java.lang包)如:Runtime ec; 然后使用该类的getRuntime()静态方法创建这个对象: ec=Runtime.getRuntime();
ec可以调用exec(String command)方法打开本地机的可执行文件或执行一个操作。
Runtime对象打开windows平台上的记事本程序和浏览器

三 字节流与字符流

Java对资源的操作是通过输入输出流完成的,根据数据源的类型可以分成字节流和字符流两种。

java的字节流继承于InputStream、OutputStream和RandomAccessFile字符流继承于Reader和Writer。

java.io包提供了大量的流类,Java把InputStream抽象类的子类创建的流对象称作字节输入流、OutputStream抽象类的子类创建的流对象称作字节输出流,Java把Reader抽象类的子类创建的流对象称作字符输入流、Writer抽象类的子类创建的流对象称作字符输出流

针对不同的源或目的地,java.io包为程序提供了相应的输入流或输出流,这些输入、输出流绝大部分都是InputStream、OutputStream、Reader或Writer的子类。

虽然java提供了很多适用于不同情况的流,我们只需要掌握标准输入输出流(System.in、System.out)、文件流(字节流和字符流)和BufferedReader、BufferedWriter就可以了,其余输入输出流的用法和它们非常相似。

3.1 InputStream类与OutputSream类

1. InputStream类提供的read方法以字节为单位顺序地读取源中的数据,只要不关闭流,每次调用read方法就顺序地读取源中的其余内容,直到源的末尾或输入流被关闭。

InputStream类有如下常用的方法。

int read()
int read(byte b[])
int read(byte b[],int off,int len)
void close()
long skip(long numBytes)

2. OutputStream流以字节为单位顺序地写文件,只要不关闭流,每次调用write方法就顺序地向目的地写入内容,直到流被关闭。

OutputStream类有如下的常用的方法。

void write(int n)
void write(byte b[])
void write(byte b[],int off,int len)
void close()

3.2 Reader类与Writer类

1.Reader类提供的read方法以字符为单位顺序地读取源中的数据。

int read():
int read(char b[]):
int read(char b[], int off, int len):
void close():
long skip(long numBytes):

2. Writer流以字符为单位顺序地写文件,每次调用write方法就顺序地向目的地写入内容。 Writer类有如下常用的方法。

void write(int n): 向输出流写入一个字符。
void write(byte b[]): 向输出流写入一个字符数组。
void write(byte b[],int off,int length): 从给定字符数组中起始于偏移量off处取len个字符写到输出流。
void close(): 关闭输出流。

3.3 关闭流

流都提供了关闭方法close(),尽管程序结束时会自动关闭所有打开的流,但是当程序使用完流后,显式地关闭任何打开的流仍是一个良好的习惯。

通过调用close()方法,可以保证操作系统把流缓冲区的内容写到它的目的地,即关闭输出流可以把该流所用的缓冲区的内容冲洗掉(通常冲洗到磁盘文件上)。

3.4 文件字节流 (FileInputStream和FileOutputSream类)

由于应用程序经常需要和文件打交道,所以InputStream专门提供了读写文件的子类:FileInputStream和FileOutputSream类。如果程序对文件的操作比较简单,比如只是顺序地读写文件,那么就可以使用FileInputStream和FileOutputSream类创建的流对文件进行读写操作。

3.4.1 文件字节输入流(FileInputStream类)

1.创建文件字节输入流
FileInputStream类创建的对象被称作文件字节输入流。

◆构造方法:
FileInputStream(String name);
FileInputStream(File file);

◆读取一个名为hello.txt的文件,建立一个文件输入流对象,如下所示:

       try { FileInputStream in = new FileInputStream("hello.txt"); 
       }
       catch (IOException e) {
          System.out.println("File read error:"+e );
         } 

2. read方法以字节为单位读文件

int read();
int read(byte b[]);
int read(byte b[],int off,int len);

3.4.2 文件字节输出流( FileOutputStream类)

1.创建文件字节输出流

FileOutputStream类创建的对象被称作文件字节输出流。

构造方法:
FileOutputStream(String name)
FileOutputStream(File file)

2.以字节为单位写文件

write方法的格式如下:
public void write(byte b[]);
public void write(byte b[],int off,int len);

3.5 文件字符流 (FileReader和FileWriter类)

1.FileReader和FileWriter用来创建文件字符输入、输出流,

构造方法:
FileReader(String filename);
FileReader(File filename);
FileWriter (String filename);
FileWriter (File filename);

2.字符输入流和输出流的read和write方法以字符为基本单位处理数据。

3.6 缓冲流(BufferedReader和BufferedWriter类)

读写能力比FileReader, FileWriter类强,可以按行读取文件,后者不可以

1.BufferedReader和BufferedWriter类创建的对象称作缓冲输入、输出流二者的源和目的地必须是字符输入流和字符输出流。

构造方法:
BufferedReader(Reader in);
BufferedWriter (Writer out);

2. BufferedReader和BufferedWriter类读写文件的方法:

readLine()// BufferedReader流读取文本行
write(String s,int off,int len)// BufferedWriter流把字符串s写到文件中

newLine(); //BufferedWriter流向文件写入一个回行符

3.7 随机流(RandomAccessFile类) :既能读文件也能写文件

使用RandomAccessFile类来创建一个随机访问文件流。RandomAccessFile类创建的流的指向既可以作为源也可以作为目的地。

构造方法:
RandomAccessFile(String name,String mode) ;
RandomAccessFile(File file,String mode) ;

◆相关方法:

seek(long a) 定位RandomAccessFile流的读写位置
getFilePointer() 获取流的当前读写位置

注意:
◆ 处理readLine()方法在读取含有非ASCII字符的文件时出现“乱码”现象的方法:

1.读取 String str=in.readLine();

2.用“iso-8859-1”重新编码 byte b[]=str.getBytes(“iso-8859-1”);

3.使用当前机器的默认编码将字节数组转化为字符串
String content=new String(b);

3.8 数组流:流的源除了可以是文件外,还可以是计算机内存(即缓冲区)

3.8.1.字节数组流(ByteArrayInputStream和ByteArrayOutputStream类)

字节数组输入流ByteArrayInputStream和字节数组输出流ByteArrayOutputStream分别使用字节数组作为流的源和目标。

◆ ByteArrayInputStream构造方法及常用方法

ByteArrayInputStream(byte[] buf);
ByteArrayInputStream(byte[] buf,int offset,int length);

public int read();顺序地从源中读出一个字节
public int read(byte[] b,int off,int len);顺序地从源中读出参数len指定的字节数

◆ ByteArrayOutputStream流构造方法及常用方法

ByteArrayOutputStream();
ByteArrayOutputStream(int size);

public void write(int b); 顺序地向缓冲区写入一个字节
public void write(byte[] b,int off,int len); 将参数b中指定的len个字节顺序地写入缓冲区
public byte[] toByteArray(); 返回输出流写入到缓冲区的全部字节

3.8. 2.字符数组流(CharArrayReader和CharArrayWriter类)

CharArrayReader和CharArrayWriter类是字符数组流,字符数组流分别使用字符数组作为流的源和目标。

3.9 数据流(DataInputStream和DataOutputStream)

数据流:允许程序按着机器无关的风格读取java原始数据(即当读取一个数值时,不再关心这个数值应当是多少个字节

DataInputStream和DataOutputStream类创建的对象称为数据输入流和数据输出流。

◆构造方法
DataInputStream(InputStream in)创建的数据输入流指向一个由参数in指定的底层输入流

DataOutputStream(OutnputStream out)创建的数据输出流指向一个由参数out指定的底层输出流

3.10 对象流(ObjectInputStream和ObjectOutputStream类)

ObjectInputStream和ObjectOutputStream类创建的对象称为对象输入流和对象输出流。

它的构造方法是:

ObjectInputStream(InputStream in)
ObjectOutputStream(OutputStream out)

◆相关方法:
writeObject(Object obj) 将一个对象obj写入到一个文件
readObject() 读取一个对象到程序中

3.11 Java 字节流、字符流和转换流之间的关系

  1. 字节流、字符流和转换流之间的关系
    (1)字节流:读取字节到内存或将字节写入硬盘文件中。

(2)字符流:将字节转换为字符(读入)或将字符转换为字节(写出)。

(3)转换流:将字节按照指定的编码格式转换为字符(读入),或将字符按照指定的编码格式转换为字节(写出),字节(字符)通向字符(字节)的桥梁。

1)字节流到字符流的桥梁怎么理解?
1、计算机存储的单位是字节,如尽管txt文本中有中文汉字这样的字符,但是对计算机而言,其是字节形式存在的
2、字节流读取是单字节读取,但是不同字符集解码成字符需要不通过个数,因此字节流读取会报错
3、 那么就需要一个流把字节流读取的字节进行缓冲而后在通过字符集解码成字符返回,因而形式上看是字符流
4、InputStreamReader流就是起这个作用,实现从字节流到字符流的转换

2)使用指定的字符集读取字节并将它们解码为字符怎么理解?
 字节本质是8个二进制位,且不同的字符集对同一字节解码后的字符结果是不同的,因此在读取字符时务必要指定合适的字符集,否则读取的内容会产生乱码

3)它使用的字符集可以通过名称指定,也可以明确指定,或者可以接受平台的默认字符集怎么理解?

  意味着InputStreamReader类有多个方法或者多个构造方法来设置字符集

4)每次调用一个InputStreamReader的read()方法都可能导致从底层字节输入流中读取一个或多个字节怎么理解?
read()方法会尝试尽量冲底层字节流中读取2个字符到字符缓冲区中,注意这里是尽量,若遇到文件最后字符,则就只能读取到1个字符,因此每次read()方法读取的字节数是不定的

5)为了实现字节到字符的有效转换,可以从基础流中提取比满足当前读取操作所需的更多字节,请考虑在BufferedReader中包装InputStreamReader
该话暂未理解,需要了解BufferedReader类后对比读取效率才可得出答案

(1)输出转换流案例:

/**
 * OutputStreamWriter转换流
 * (1)OutputStreamWriter(OutputStream out);使用默认编码格式,将字符编码成字节
 * (2)OutputStreamWriter(OutputStream out,String charsetName);使用指定编码格式,将字符编码成字节
 */
private static void osw01() throws Exception {
    OutputStream os = new FileOutputStream("E:\\kankan\\1.txt");
    OutputStreamWriter osw = new OutputStreamWriter(os, "utf-8");
    osw.write("你好");
    osw.flush();
    osw.close();
}
```java
(2)输入转换流案例:
/*
 * InputStreamReader转换流
 * (1)InputStreamReader(InputStream in);使用默认的编码格式,将字节转换为字符
 * (2)InputStreamReader(InputStream in,String charsetName);使用指定编码格式,将字节转换为字符
 */
private static void isr01() throws IOException {
    InputStream is = new FileInputStream("E:\\kankan\\1.txt");
    InputStreamReader isr = new InputStreamReader(is,"utf-8");
    char[] chs = new char[1024];
    int len = 0;
    while((len=isr.read(chs))!=-1){
        System.out.println(new String(chs,0,len));
    }
    isr.close();
}

四 序列化(实现Serializable接口)与对象克隆(调用clone方法)

◆所谓序列化:一个类如果实现了Serializable接口,那么这个类创建的对象就是所谓序列化的对象。

◆如果一个“复制品”实体的变化不会引起原对象实体发生变化,反之亦然。这样的复制品称为原对象的一个克隆对象或简称克隆。

◆ 一个对象调用clone()方法就可以获取该对象的克隆对象。

◆对象输入流通过对象的序列化信息来得到当前对象的一个克隆。

五 文件锁 :避免出现几个程序同时处理同一个文件的情景(如:读写文件,更新文件)(FileLock、FileChannel类)

◆FileLock、FileChannel类处理Java提供的文件锁功能。它们分别在java.nio和java.nio.channels包中。

◆ 输入、输出流读写文件时可以使用文件锁。

◆ RondomAccessFile创建的流在读写文件时使用文件锁的步骤如下:

1.先使用RondomAccessFile流建立指向文件的流对象,该对象的读写属性必须是rw,例如:

RandomAccessFile input=new RandomAccessFile(“Example.java”,“rw”);

2.input流调用方法getChannel()获得一个连接到底层文件的FileChannel对象(信道),例如
FileChannel channel=input.getChannel();

3.信道调用tryLock()或lock()方法获得一个FileLock(文件锁)对象,这一过程也称作对文件加锁,例如:FileLock lock=channel.tryLock();

六 使用Scanner解析文件

使用Scanner类和正则表达式来解析文件。

1.使用默认分隔标记解析文件

创建Scanner对象,并指向要解析的文件,例如:
File file = new File(“hello.java”);
Scanner sc = new Scanner(file);
sc将空白作为分隔标记

相关方法:
next() 依次返回file中的单词
hasNext() 判断file最后一个单词是否已被next()方法返回

2.使用正则表达式作为分隔标记解析文件
创建Scanner对象,指向要解析的文件,并使用useDelimiter方法指定正则表达式作为分隔标记,例如:

File file = new File(“hello.java”);
Scanner sc = new Scanner(file);
sc.useDelimiter(正则表达式); sc将正则表达式作为分隔标记

相关方法:

next() 依次返回file中的单词
hasNext() 判断file最后一个单词是否已被next()方法返回

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值