14、Java文件操作stream、File、IO

时间:2023-03-08 17:29:01

1、文件操作涉及到的基本概念

File

File类 是文件操作的主要对象
中文意义就是 文件 顾名思意 万物皆文件,在计算上看到的所有东西都是文件保存,不管是你的图片、视频、数据库数据等等都是按照基本的二进制规则保存到计算机中的存储系统中。 Java中使用File类:
得到一个文件对象:
      String filename = "/tmp/user/java/bin/javac.sh";
      File file = new File(filename);
创建一个目录:
      String dirname = "/tmp/user/java/bin";
      File d = new File(dirname);
      // 现在创建目录
      d.mkdirs();

字节流和字符流

字节流:字节流读取的时候,读到一个字节就返回一个字节;主要用于读取图片,MP3,AVI视频文件。

字符流:字符流使用了字节流读到一个或多个字节,如读取中文时,就会一次读取2个字节。只要是处理纯文本数据,就要优先考虑使用字符流。
区别:
字节流操作的基本单元为字节;字符流操作的基本单元为Unicode码元。
字节流默认不使用缓冲区;字符流使用缓冲区。
字节流通常用于处理二进制数据,实际上它可以处理任意类型的数据,但它不支持直接写入或读取Unicode码元;字符流通常处理文本数据,它支持写入及读取Unicode码元。

IO

流:代表任何有能力产出数据的数据源对象或者是有能力接受数据的接收端对象 ;其作用是为数据源和目的地建立一个输送通道
IO流:是程序中一套用于数据传输的机制。IO流是Input流和Output流的简称。流的输入输出是以程序为参照物。
1、输入流

数据从外部流向程序。例如读取文件,就是从外部流入程序。

2、输出流

数据从程序流向外部。例如将程序中的数据写入到文件中。

2、Java文件操作

创建文件

我们可以从中创建一个File对象

  • 路径名

  • 父路径名和子路径名

  • URI(统一资源标识符)

我们可以使用File类的以下构造函数之一创建一个文件:

File(String pathname)
File(File parent, String child)
File(String parent, String child)
File(URI uri)
   
##如果我们有一个文件路径名字符串test.txt,我们可以创建一个抽象路径名作为下面的代码。
File dummyFile = new File("test.txt");    
boolean fileCreated  = dummyFile.createNewFile();

使用File对象,我们可以创建新文件,删除现有文件,重命名文件,更改文件的权限等。

File类中的isFile()和isDirectory()告诉File对象是否表示文件或目录。

文件的存在:

我们可以使用File类的exists()方法检查File对象的抽象路径名是否存在。

boolean fileExists = dummyFile.exists();

当前工作目录:

JVM的当前工作目录是根据我们如何运行java命令来设置的。

我们可以通过读取user.dir系统属性来获取JVM的当前工作目录,如下所示:

String workingDir = System.getProperty("user.dir");

使用System.setProperty()方法更改当前工作目录。

System.setProperty("user.dir", "C:\\myDir");

要在Windows上指定C:\ test作为user.dir系统属性值,我们运行如下所示的程序:

java -Duser.dir=C:\test your-java-class

3、Java输入流

1、分类

抽象基本组件是InputStream类。

InputStream
|
+--FileInputStream
|
+--ByteArrayInputStream
|
+--PipedInputStream
|
+--FilterInputStream
|
+--BufferedInputStream
|
+--PushbackInputStream
|
+--DataInputStream
|
+--ObjectInputStream

我们有FileInputStream,ByteArrayInputStream和PipedInputStream,FilterInputStream的具体类。

方法

超类InputStream包含从输入流读取数据的基本方法,所有具体类都支持这些方法。

对输入流的基本操作是从其读取数据。InputStream类中定义的一些重要方法在下表中列出。

ID 方法/说明
1 read() 读取一个字节并将读取的字节作为int返回。当到达输入流的结尾时,它返回-1。
2 read(byte[] buffer) 读取最大值直到指定缓冲区的长度。它返回在缓冲区中读取的字节数。如果到达输入流的结尾,则返回-1。
3 read(byte [] buffer,int offset,int length) 读取最大值到指定长度字节。 数据从偏移索引开始写入缓冲区。它返回读取的字节数或-1,如果到达输入流的结束。
3 close() 关闭输入流
4 available() 返回可以从此输入流读取但不阻塞的估计字节数。

2、文件输入流

在Java I/O中,流意味着数据流。流中的数据可以是字节,字符,对象等。

要从文件读取,我们需要创建一个FileInputStream类的对象,它将表示输入流。

String srcFile = "test.txt";
FileInputStream fin = new FileInputStream(srcFile);

3、缓冲输入流

BufferedInputStream通过缓冲数据向输入流添加功能。

它维护一个内部缓冲区以存储从底层输入流读取的字节。

我们创建缓冲区输入流如下:

String srcFile =“test.txt";BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));

以下代码显示如何使用BufferedInputStream从文件读取。

import java.io.BufferedInputStream;
import java.io.FileInputStream; public class Main {
public static void main(String[] args) {
  String srcFile = "test.txt";
  try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
      srcFile))) {
    // Read one byte at a time and display it
    byte byteData;
    while ((byteData = (byte) bis.read()) != -1) {
      System.out.print((char) byteData);
    }
  } catch (Exception e2) {
    e2.printStackTrace();
  }
}
}

4、Java双输出流

1、基本概念

在抽象超类OutputStream中定义了三个重要的方法:write(),flush()和close()。

write()方法将字节写入输出流。

它有三个版本,允许我们一次写一个字节或多个字节。

flush()方法用于将任何缓冲的字节刷新到数据宿。

close()方法关闭输出流。

要使用BufferedOutputStream装饰器以更好的速度写入文件,请使用以下语句:

BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("your output file path"));

要将数据写入ByteArrayOutputStream,请使用

ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(buffer); // buffer is a byte   array

2、Java 文件输出流

要写入文件,我们需要创建一个FileOutputStream类的对象,它将表示输出流。

// Create a file output stream
String destFile = "test.txt";
FileOutputStream fos   = new FileOutputStream(destFile);

3、Java 数据输出流

DataOutputStream可以将Java基本数据类型值写入输出流。

DataOutputStream类包含一个写入数据类型的写入方法。它支持使用writeUTF(String text)方法将字符串写入输出流。

要将Java原始数据类型值写入名为primitives.dat的文件,我们将按如下所示构造DataOutputStream的对象:

DataOutputStream dos = new DataOutputStream(new FileOutputStream("primitives.dat"));

5、常用操作实战

1、创建、删除文件夹

String path = "F:\\test";
File myFile = new File(path); if (!myFile.exists()) {
   // 创建文件夹
   myFile.mkdir();
   // myFile.mkdirs();    // 删除文件夹
   myFile.delete();
} // mkdirs()可以建立多级文件夹, mkdir()只会建立一级的文件夹

2、创建、删除文件

String content = "Hello World";

// 第一种方法:根据文件路径和文件名
String path = "F:\\test";
String filename = "test.txt";
File myFile = new File(path,filename); // 第二种方法
String file = "F:\\test\\test.txt";
File myFile = new File(file); if (!myFile.exists()) {
   // 创建文件(前提是目录已存在,若不在,需新建目录即文件夹)
   myFile.createNewFile();    // 删除文件
   myFile.delete();
}

3、写入文件

// 第一种:字节流FileOutputStream
FileOutputStream fop = new FileOutputStream(myFile);
byte[] contentInBytes = content.getBytes();
fop.write(contentInBytes);  
fop.flush();  
fop.close(); // 第二种:FileWriter(参数true为追加内容,若无则是覆盖内容)
FileWriter fw = new FileWriter(myFile,true);
fw.write(content);
fw.close(); // 第三种:BufferedWriter
BufferedWriter bw = new BufferedWriter(new FileWriter(myFile,true));
bw.write(content);  
bw.flush();  
bw.close(); // 第四种:打印流PrintStream和PrintWriter
// 字节打印流:PrintStream
// 字符打印流:PrintWriter PrintWriter pw = new PrintWriter(new FileWriter(myFile,true));  
pw.println(content);      // 换行
pw.print(content);        // 不换行
pw.close(); // 常用BufferedWriter和PrintWriter

4、读取文件

FileInputStream:

// 第一种:以字节为单位读取文件,常用于读二进制文件,如图片、声音、影像等文件。
InputStream in = new FileInputStream(myFile); // 一次读一个字节
int tempbyte;  
while ((tempbyte = in.read()) != -1) {  
   System.out.write(tempbyte);  
}  
in.close(); // 一次读多个字节
int byteread = 0;
byte[] tempbytes = new byte[100];
ReadFromFile.showAvailableBytes(in);
while ((byteread = in.read(tempbytes)) != -1) {  
   System.out.write(tempbytes, 0, byteread);  
}   // System.out.write()方法是字符流,System.out.println()方法是字节流

InputStreamReader:

// 第二种:以字符为单位读取文件,常用于读文本,数字等类型的文件
Reader reader = new InputStreamReader(new FileInputStream(myFile)); // 一次读一个字节
int tempchar;  
while ((tempchar = reader.read()) != -1) {  
   // 对于windows下,\r\n这两个字符在一起时,表示一个换行。 
   // 但如果这两个字符分开显示时,会换两次行。 
   // 因此,屏蔽掉\r,或者屏蔽\n。否则,将会多出很多空行。 
   if (((char) tempchar) != '\r') {  
       System.out.print((char) tempchar);  
  }  
}  
reader.close(); // 一次读多个字节
char[] tempchars = new char[30];  
int charread = 0;  
// 读入多个字符到字符数组中,charread为一次读取字符数  
while ((charread = reader.read(tempchars)) != -1) {  
   // 同样屏蔽掉\r不显示  
   if ((charread == tempchars.length) && (tempchars[tempchars.length - 1] != '\r')) {  
       System.out.print(tempchars);  
  } else {  
       for (int i = 0; i < charread; i++) {  
           if (tempchars[i] == '\r') {  
               continue;  
          } else {  
               System.out.print(tempchars[i]);  
          }  
      }  
  }  
}

BufferedReader:

// 第三种:以行为单位读取文件,常用于读面向行的格式化文件
BufferedReader reader = new BufferedReader(new FileReader(myFile));
String tempString = null;  
int line = 1;  
// 一次读入一行,直到读入null为文件结束  
while ((tempString = reader.readLine()) != null) {  
   // 显示行号  
   System.out.println("line " + line + ": " + tempString);  
   line++;  
}  
reader.close();   // 常用BufferedReader

5、遍历文件(以删除一个文件夹下所有文件为例)

File[] files=myFile.listFiles();  
for(int i=0;i<files.length;i++){  
   if(files[i].isDirectory()){  
       files[i].delete();  
  }  
}  

14、Java文件操作stream、File、IO