不同介質間進行數據交互,使用數據流
來實現。
InputStream
是字節輸入流
,同時也是抽象類,只提供方法聲明,不提供方法的具體實現。
FileInputStream 是InputStream子類。
OutputStream
是字節輸出流
,同時也是抽象類,只提供方法聲明,不提供方法的具體實現。
FileOutputStream 是OutputStream子類。
關閉流
注意一點,輸入流輸出流使用完之後都應該關閉。如果不關閉,會產生對資源佔用的浪費。一般關閉有兩種方式。
一. try
中關閉xx.close()
;
在try的作用域裏關閉文件輸入流,但這樣做有一個弊端;如果文件不存在,或者讀取的時候出現問題而拋出異常,那麼就不會執行這一行關閉流的代碼,存在巨大的資源佔用隱患。 不推薦使用
二. finally
關閉
標準的關閉流的方式
- 首先把流的引用聲明在try的外面,如果聲明在try裏面,其作用域無法抵達finally.
- 在finally關閉之前,要先判斷該引用是否爲空
- 關閉的時候,需要再一次進行try catch處理
這種方式嚴謹,但是看上去很繁瑣,所以寫不重要的或者測試代碼的時候,都會採用try的方式。
三. try()
方式
把流定義在try()裏,try,catch或者finally結束的時候,會自動關閉。所有的流,都實現了一個接口叫做AutoCloseable
,任何類實現了這個接口,都可以在try()中進行實例化。 並且在try, catch, finally結束的時候自動關閉,回收相關資源。
try (FileInputStream fis = new FileInputStream(f))
{ … }
學習例程,使用輸入流讀出txt中的內容;使用輸出流將指定字符輸出到txt
package stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try {
File f1 =new File("f:/testfile/file.txt");
FileInputStream fis =new FileInputStream(f1); //創建基於文件的輸入流
byte[] all =new byte[(int) f1.length()]; //創建字節數組,其長度就是文件的長度
fis.read(all); //以字節流的形式讀取文件所有內容
for (byte b : all) {
System.out.print(b);
System.out.print(',');
}
fis.close(); //每次使用完流,都應該進行關閉
File f2 = new File("f:/testfile/stream-out.txt");
byte data[] = {73,32,76,79,86,69,32,67,104,101,110,103,68,117,46};
FileOutputStream fos = new FileOutputStream(f2); // 創建基於文件的輸出流
fos.write(data); // 把數據寫入到輸出流
fos.close(); // 關閉輸出流
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
學習例程:輸出流-當文件目錄不存在時
package stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
String realPath = "";
String filepath = "f:/testfile/0319/file.txt";
String SplitPath[] = filepath.split("/");
for(int i=0; i < SplitPath.length - 1 ;i++) {
realPath = realPath + SplitPath[i];
File f = new File(realPath);
if(f.exists());
else f.mkdir();
realPath += "/";
}
System.out.println(realPath);
try {
File f = new File(filepath);
byte data[] = {73,32,76,79,86,69,32,67,104,101,110,103,68,117,46};
FileOutputStream fos = new FileOutputStream(f); // 創建基於文件的輸出流
fos.write(data); // 把數據寫入到輸出流
fos.close(); // 關閉輸出流
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
合併文件,拆分文件
測試了一個.pptx的文件,程序能正確拆分,並能正確合併(打開無錯誤)。
package stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
public class OperateFile {
/**
* @param srcFile 要拆分的源文件
* @param eachSize 按照這個大小,拆分
*/
public static void splitFile(File srcFile,int eachSize) {
if (0 == srcFile.length())
throw new RuntimeException("文件長度爲0,不可拆分");
byte[] fileContent = new byte[(int) srcFile.length()];
try {
FileInputStream fis = new FileInputStream(srcFile);
fis.read(fileContent);
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 計算需要被劃分成多少份子文件
int fileNumber;
if (0 == fileContent.length % eachSize)
fileNumber = (int) (fileContent.length / eachSize);
else
fileNumber = (int) (fileContent.length / eachSize) + 1;
for (int i = 0; i < fileNumber; i++) {
String eachFileName = srcFile.getName() + i;
File eachFile = new File(srcFile.getParent()+"//splitfile", eachFileName);
byte[] eachContent;
if (i != fileNumber - 1)
eachContent = Arrays.copyOfRange(fileContent, eachSize * i, eachSize * (i + 1));
else
eachContent = Arrays.copyOfRange(fileContent, eachSize * i, fileContent.length);
try {
FileOutputStream fos = new FileOutputStream(eachFile); // 寫出去
fos.write(eachContent);
fos.close();
System.out.printf("輸出子文件%s,其大小是 %d字節%n", eachFile.getAbsoluteFile(), eachFile.length());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/* 合併文件
* @param part 合併的文件共幾份
* @param eachhsize 每一份文件的大小
*/
public static void mergeFile(int part,int eachsize) {
File destDirectory = new File("f:/testfile/splitfile/0321.pptx");
if(destDirectory.canExecute())
destDirectory.delete();
try {
FileOutputStream fos = new FileOutputStream(destDirectory,true);
int count = 0;
while(count<part) {
File srcDirectory = new File("f:/testfile/splitfile/0321.pptx"+count);
FileInputStream fis = new FileInputStream(srcDirectory);
byte[] srcLength = new byte[(int)srcDirectory.length()];
fis.read(srcLength);
fos.write(srcLength);
count = count+1;
fis.close();
}
fos.close();
}catch(Exception e) {
e.printStackTrace();
}
}
}
public class Main {
public static void main(String[] args) {
int eachSize = 100 * 1024; // 100k
File srcFile = new File("f:/testfile/0321.pptx");
OperateFile.splitFile(srcFile, eachSize);
OperateFile.mergeFile(8,eachSize);
}
}