ファイルに対する操作
//通过将给定路径名字符串转换成抽象路径名来创建一个新 File 实例。
File(String pathname)
public String getAbsolutePath();//返回抽象路径名的绝对路径名字符串。
public boolean mkdirs();//创建此抽象路径名指定的目录,包括创建必需但不存在的父目录。
public boolean mkdir()//创建此抽象路径名指定的目录。
//返回一个抽象路径名数组,这些路径名表示此抽象路径名所表示目录中的文件。
public File[] listFiles()
// 删除此抽象路径名表示的文件或目录。
public boolean delete()
//测试此抽象路径名表示的文件是否是一个目录。
public boolean isDirectory()
//测试此抽象路径名表示的文件或目录是否存在。
public boolean exists()
mkdir() でファイルインスタンスを作成する
public static void main(String[] args) {
String path = "abcd\\sdf\\nkunoi\\a"; //给出创建文件的路径
//在E盘下面创建文件,将文件路径添加为文件
File file = new File("E:\\" + path);
//file.exists();判断当前目录是否存在
if(file.exists()) {
//file.mkdirs();先判断当前目录下是否存在路径文件,
//存在返回false,不存在,生产路径文件返回true
file.mkdirs()
}
}
E ディスクの下に生成されるパス。
注意してください。
// file.mkdirs(); 可以创建多级目录(文件夹),父目录不一定存在。
//即可以生成abcd\\sdf\\nkunoi\\a 的所有目录
// file.mkdir();只能创建一级目录(文件夹),且父目录必须存在,否则创建失败。
//如果要创建sdf目录,那么abcd目录必须存在。nkunoi目录也一样,sdf目录必须存在
ディレクトリ内のすべてのファイルを再帰的にスキャンします
現在のディレクトリ内のすべてのファイルをスキャンしたい場合は、1 つずつ再帰的にスキャンできます。
コードは次のとおりです。
package com.dxc.about_dir.test;
import java.io.File;
import java.io.FileFilter;
public class TestForDir {
public static void scanDir(File curDir) {
curDir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (pathname.isDirectory()) {
//检查这个对象是否是文件
//是文件,则输出这个目录
System.out.println("目录:" + pathname);
//递归扫描该目录下的文件
scanDir(pathname);
return false;
}
//不是目录文件,并且判断该文件是否以".java"结尾
if (pathname.getName().endsWith(".java")) {
System.out.println("取得绝对路径:" +
pathname.getAbsolutePath());//取得绝对路径
System.out.println("取得相对路径:" +
pathname.getPath());//取得相对路径
}
return false;
}
});
}
public static void main(String[] args) {
File file = new File(".");
scanDir(file);
}
}
これは現在のディレクトリにあるファイルです
これはコードをスキャンした結果です
ファイルに対するストリーム (ストリーム) および IO 操作
Java ストリーム (Stream)、ファイル (File)、および IO
Java.io パッケージには、入出力の操作に必要なほぼすべてのクラスが含まれています。これらのストリーム クラスはすべて、入力ソースと出力先を表します。
Java.io パッケージのストリームは、プリミティブ型、オブジェクト、ローカライズされた文字セットなど、さまざまな形式をサポートしています。
ストリームはデータのシーケンスとして理解できます。入力ストリームはソースからのデータの読み取りを表し、出力ストリームはターゲットへのデータの書き込みを表します。
Java は I/O に対する強力かつ柔軟なサポートを提供するため、ファイル転送やネットワーク プログラミングでより広く使用されています。
ただし、このセクションでは、ストリームと I/O に関連する最も基本的な機能について説明します。例を通してこれらの関数を学びます。
ファイルを読み取る
FileInputStream(パス);
このストリームはファイルからデータを読み取るために使用され、そのオブジェクトはキーワード new を使用して作成できます。
- public void close() throws IOException{}
このファイル入力ストリームを閉じ、このストリームに関連付けられたすべてのシステム リソースを解放します。IOException がスローされます。 - protected void Finalize() throws IOException {}
このメソッドは、ファイルへの接続をクリアします。ファイル入力ストリームが参照されなくなったら、必ず close メソッドを呼び出してください。IOException がスローされます。 - public int read(int r)throws IOException{}
このメソッドは、InputStream オブジェクトから指定されたバイトのデータを読み取ります。整数値として返されます。データの次のバイトを返すか、終わりに達した場合は -1 を返します。 - public int read(byte[] r) throws IOException{}
このメソッドは、入力ストリームから r.length バイトを読み取ります。読み取られたバイト数を返します。ファイルの終わりの場合は -1 を返します。 - public int available() throws IOException{}
この入力ストリームの次のメソッド呼び出しによってブロックされることなく、この入力ストリームから読み取ることができるバイト数を返します。整数値を返します。
上記で作成した abcd\sdf\nkunoi\a ディレクトリの下に txt ファイルを作成しました
この txt ファイルを読み込むコードは次のとおりです
package com.dxc.about_io.test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TestForFileIO {
public static void main(String[] args) {
FileInputStream fis;
try {
//该流用于从文件中读取数据
fis = new FileInputStream(
"E:\\abcd\\sdf\\nkunoi\\a\\b\\c\\1111.txt");
//从fis流中读取第一个字节
int value = fis.read();
while (value != -1) {
System.out.print((char) value);//输出读取的字节
value = fis.read();//举行读取字节,到结尾返回-1,循环结束
}
fis.close();//关闭文件
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
として出力
ファイルを書き込む
ファイル出力ストリーム
このクラスは、ファイルを作成し、ファイルにデータを書き込むために使用されます。
ストリームが出力用にファイルを開く前に宛先ファイルが存在しない場合、ストリームはファイルを作成します。
- public void close() throws IOException{}
このファイル入力ストリームを閉じ、このストリームに関連付けられたすべてのシステム リソースを解放します。IOException がスローされます。 - protected void Finalize() throws IOException {}
このメソッドは、ファイルへの接続をクリアします。ファイル入力ストリームが参照されなくなったら、必ず close メソッドを呼び出してください。IOException がスローされます。 - public void write(int w)throws IOException{}
このメソッドは、指定されたバイトを出力ストリームに書き込みます。 - public void write(byte[] w) は、
指定された配列内の w.length のバイトを OutputStream に書き込みます。
ファイルの読み取りと書き込みのコード例
次のファイルを読み込み、別のディレクトリに書き込みます。これは私たちがよくコピー操作と呼ぶものです。
168MBはまだかなり大きいです
次の 3 つのコード例は、コード コピーのさまざまな利点と欠点を示すために使用されています
。
//下面代码将ABSOLUTE_ROOT 目录下的targetFile 复制写出,再写入到targetFilePath 目录下
public static void main(String[] args) {
String targetFile = "dxc.mp4";//我的目标文件
String targetFilePath = "D:\\a\\";//写入的目录
String ABSOLUTE_ROOT = "E:\\abcd\\sdf\\nkunoi\\a\\b\\c\\";//目标文件的目录
File inFile = new File(ABSOLUTE_ROOT + targetFile);//打开目标文件
File outFile = new File(targetFilePath + targetFile);//打开写入文件
long startTime = System.currentTimeMillis();//开始复制的时间
try {
//该流用于从文件中读取数据
FileInputStream fis = new FileInputStream(inFile);
//该流用于从文件中读取数据
FileOutputStream fos = new FileOutputStream(outFile );
int value = fis.read();//从fis流读入一个字节
while(value != -1) {
fos.write(value);//将读入的value值写入fos流
value = fis.read();//读下一个字节
}
fis.close();//关闭文件
fos.close();//关闭文件
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();//复制结束
endTime -= startTime;//复制用时
System.out.println(endTime/1000 + "秒" +endTime%1000 + "毫秒");
}
このときのCPU使用率と
プログラム全体の実行時間を見ると、
プログラム全体の実行に合計11分以上かかっていることがわかります。
次に、ビデオ ファイルを D:\a ディレクトリにコピーします。
コード 2: すべてのバイトを直接読み取ってから書き込みます。
public static void main(String[] args) {
String targetFile = "dxc.mp4";
String targetFilePath = "D:\\a\\";
File inFile = new File("E:\\abcd\\sdf\\nkunoi\\a\\b\\c\\" + targetFile);
File outFile = new File(targetFilePath + targetFile);
long startTime = System.currentTimeMillis();
try {
FileInputStream fis = new FileInputStream(inFile);
FileOutputStream fos = new FileOutputStream(outFile );
long fileSize = inFile.length();//得到文件的大小
byte[] buffer = new byte[(int) fileSize];//申请文件大小的空间,
fis.read(buffer);//将文件写入byte[]里面;
fos.write(buffer); //将文件写出
fis.close();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
endTime -= startTime;
System.out.println(endTime/1000 + "秒" +endTime%1000 + "毫秒");
}
実行時間:
時間が 11 分から 466 ミリ秒に変更されました。速度プロンプトが非常に速い
/
十分な大きさのスペースを申請したため、すべてのメモリ使用量が非常に深刻で、大幅な増加が見られます。書き込まれるファイルが十分に大きい場合、メモリの使用量が直接的に爆発的に増加するため、この方法はすべてお勧めできません。
もう少し速く、メモリ使用量にもう少し優しい、より良い方法はありますか。
失われたファイルを一度に少しずつ読み出して書き込み、一定のバイト数を読み出して再度書き込み、読み取りが終了するまで繰り返すことができます。
たとえば、18 バイトがある場合、一度に 4 バイトの読み書きができ、4 回後に再び 2 バイトの読み書きができ、終了します。
コード 3:
public static void main(String[] args) {
final int BUFFER_SIZE = 1 << 16;//数组大小
String targetFile = "dxc.mp4";
String targetFilePath = "D:\\a\\";
File inFile = new File("E:\\abcd\\sdf\\nkunoi\\a\\b\\c\\" + targetFile);
File outFile = new File(targetFilePath + targetFile);
long startTime = System.currentTimeMillis();
try {
FileInputStream fis = new FileInputStream(inFile);
FileOutputStream fos = new FileOutputStream(outFile);
int fileSize = (int) inFile.length();
byte[] buffer = new byte[BUFFER_SIZE];//申请一定的空间
int readLen;
while (fileSize > 0) {
//先判断文件剩余大小,有没有数组大小大
//大于数组大小,就可以读写数组大小的长度;
//小于数组大小,就可以直接读写文件长度。
readLen = fileSize >= BUFFER_SIZE ? BUFFER_SIZE : fileSize;
//读写readLen大小的文件
readLen = fis.read(buffer, 0, readLen);
//文件总大小,减去已经读过的大小
fileSize -= readLen;
//写出文件
fos.write(buffer, 0, readLen);
}
fis.close();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
endTime -= startTime;
System.out.println(endTime/1000 + "秒" +endTime%1000 + "毫秒");
}
dxc.mp4 の読み書きにかかる時間は
わずか 102 ミリ秒で、非常に高速であり
、メモリ使用量も非常に少ないことがわかります。
次に、ファイルの読み取りと書き込みについて知っておく必要があります。バイトごとに読み取りと書き込みをしないでください。速度が遅すぎます。また、一度にすべての読み取りと書き込みはできず、メモリの使用量が多すぎます。ただし、毎回一定の長さの読み取りと書き込みができるようにサイズを設定できます。これにより、速度が向上するだけでなく、メモリの過度の使用も回避できます。