自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

為什么你總是不明白Java IO流?這是我用過(guò)的最好工具

開發(fā) 前端
在任何編程語(yǔ)言中,數(shù)據(jù)的IO都是比較常見并相當(dāng)重要的。Guava作為工具型類庫(kù),主要是幫助開發(fā)者封裝常用、重復(fù)的操作,開放出簡(jiǎn)介的API,不僅能讓讓代碼更加整潔, 同時(shí)對(duì)開發(fā)出穩(wěn)健程序也是比不可少的。

哈嘍,大家好,我是指北君,今天我們來(lái)講一講java中的IO流與Guava。

Guava IO

日常系統(tǒng)交互中,文件的上傳下載都是常見的,一般我們會(huì)通過(guò)jdk提供的IO操作庫(kù)幫助我們實(shí)現(xiàn)。IO指的是數(shù)據(jù)相對(duì)當(dāng)前操作程序的入與出,將數(shù)據(jù)通過(guò) 輸出流從程序輸出,或者通過(guò)輸入流將數(shù)據(jù)(從文件、網(wǎng)絡(luò)、數(shù)據(jù)等)寫入到程序,這里的IO指的是基于流作為載體進(jìn)行數(shù)據(jù)傳輸。如果把數(shù)據(jù)比作合理的水,河就是IO流,也是數(shù)據(jù)的載體。

Java為我們提供了非常多的操作IO的接口與類,幫助開發(fā)者實(shí)現(xiàn)不同源間的數(shù)據(jù)傳輸,比如硬盤文件、網(wǎng)絡(luò)傳輸、應(yīng)用調(diào)用間的數(shù)據(jù)交互與傳遞。今天我們來(lái)簡(jiǎn)單了解下Java中的流 以及在Guava工具包中,針對(duì)IO操作做了什么樣的封裝與設(shè)計(jì)。

分類

在java.io包中有非常多的IO相關(guān)接口,我們可以根據(jù)流的輸出類型、處理對(duì)象以及功能將其分為以下幾種類型:

  • 按數(shù)據(jù)流向

輸入流 (java.io.InputStream)用于實(shí)現(xiàn)將數(shù)據(jù)讀入到程序

輸出流 (java.io.OutputStream)用于實(shí)現(xiàn)將數(shù)據(jù)從程序?qū)懗?/p>

  • 按操作單位

字節(jié)流以字節(jié)(byte)為單位進(jìn)行數(shù)據(jù)的讀、寫 (其中針對(duì)文件也提供了按基礎(chǔ)數(shù)據(jù)類型的讀與寫DataInpoutStream,也就是按照J(rèn)ava基礎(chǔ)類型所占字節(jié)數(shù)來(lái)進(jìn)行定量字節(jié)讀取并合并)

字符流以字符(char)為單位進(jìn)行數(shù)據(jù)的讀、寫,此時(shí)需要注意字符編碼

區(qū)分:

字節(jié)流一般以Stream結(jié)尾 字符流一般以Reader或Writer結(jié)尾

  • 按操作方式

讀 (java.io.Reader)主要針對(duì)字符流的讀取操作

寫 (java.io.Writer)主要針對(duì)字符流的寫出操作

  • 按功能

緩存流按字節(jié)進(jìn)行數(shù)據(jù)讀寫時(shí),通過(guò)緩沖批量寫入來(lái)提高傳輸效率

轉(zhuǎn)換流實(shí)現(xiàn)輸入/出與讀/寫方式間的轉(zhuǎn)換

常用的流

  • 操作文件的java.io.FileinputStream/FileOutputStream java.io.FileReader/FileWriter
  • 通用的字節(jié)流java.io.InputStreamReader/outputStreamWriter
  • 緩沖流java.io.BufferedReader/BufferedWriter java.io.BufferedInputStream/BufferedOutputStream
  • 數(shù)據(jù)流java.io.DataInpoutStream/DataOutputStream
  • 功能型的java.io.PrintWriter/PrintStream
  • 對(duì)象序列化相關(guān)的java.io.ObjectInputStream/ObjectOutputStream

可見,提供的IO對(duì)象基本都是成對(duì)出現(xiàn)的,用以完成數(shù)據(jù)的輸入輸出,實(shí)現(xiàn)程序與外部載體間的數(shù)據(jù)交換

示例

下面我們通過(guò)一些常用示例來(lái)看看IO的使用的場(chǎng)景與使用方法:

  • 文件復(fù)制
  • 文件的合并
  • 讀取文件內(nèi)容為字符串
  • 字節(jié)數(shù)組轉(zhuǎn)換成流
  • 對(duì)象序列化與反序列化
  • 流的轉(zhuǎn)換
  • ......
  • 文件復(fù)制
@Test
public void copyByBytes() throws IOException {
String root = FileTests.class.getResource("/").getPath();

FileInputStream fis = new FileInputStream(new File(root,"/start.bat"));
FileOutputStream fos = new FileOutputStream(root+"/out2.bat");

byte[] buff = new byte[100];

int b;
while ( (b = fis.read(buff))!=-1 ){
fos.write(buff, 0, b);
}
// close
}
  • 文件合并
@Test
public void mergeFiles() throws IOException {
File file1 = new File("E:\\_projects\\sucls\\blog\\my_study\\guava\\guava-io\\src\\test\\java\\com\\sucls\\blog\\guava\\io\\category\\FileTests.java");
File file2 = new File("E:\\_projects\\sucls\\blog\\my_study\\guava\\guava-io\\src\\test\\java\\com\\sucls\\blog\\guava\\io\\category\\StreamTests.java");

Enumeration<InputStream> ins = Collections.enumeration(Arrays.asList(
new FileInputStream(file1),
new FileInputStream(file2)
));

SequenceInputStream sequenceInputStream = new SequenceInputStream(ins);

FileOutputStream fos = new FileOutputStream(root+"/out4");

byte[] buff = new byte[100];

int read; // 真實(shí)讀取到的字節(jié)數(shù)
while ( (read = sequenceInputStream.read(buff)) !=-1){
fos.write(buff, 0, read);
}

fos.close();
}
  • 讀取文件內(nèi)容為字符串
@Test
public void readStringFromFile() throws IOException {
FileReader fileReader = new FileReader(new File(this.getClass().getResource("/").getPath(),"/start.bat"));

StringBuilder stringBuilder = new StringBuilder();

int i;
while ( (i = fileReader.read())!=-1 ){
stringBuilder.append( (char)i ); // 按字符讀取
}

System.out.println( stringBuilder ); // 文件內(nèi)容
}
  • 字節(jié)數(shù)組轉(zhuǎn)換成流
@Test
public void bytesToStream(){
byte [] data = new byte[1024]; // 來(lái)源于其他數(shù)據(jù)源

ByteArrayInputStream inputStream = new ByteArrayInputStream(data);

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

int v;
while ( (v=inputStream.read())!=-1 ){
outputStream.write(v);
}

System.out.println( Arrays.toString( outputStream.toByteArray() ));
}
  • 對(duì)象序列化與反序列化
@Test
public void objectToFile() throws IOException {

Person person = new Person();
person.setName("張三").setAge(25);

String root = FileTests.class.getResource("/").getPath();

FileOutputStream fos = new FileOutputStream(new File(root,"/person"));
ObjectOutputStream oos = new ObjectOutputStream(fos);

oos.writeObject(person);
}

@Test
public void fileToObject() throws IOException, ClassNotFoundException {
String root = FileTests.class.getResource("/").getPath();

FileInputStream fis = new FileInputStream(new File(root,"/person"));
ObjectInputStream ois = new ObjectInputStream(fis);

Person person = (Person) ois.readObject();
System.out.println( person );
}
  • 流的轉(zhuǎn)換 將字節(jié)流轉(zhuǎn)換成字符流來(lái)操作,同樣以文件復(fù)制為例
@Test
public void copyByBuffer() throws IOException {
String root = FileTests.class.getResource("/").getPath();

FileInputStream fis = new FileInputStream(new File(root,"/start.bat"));
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);

FileOutputStream fos = new FileOutputStream(root+"/out3.bat");
OutputStreamWriter osw = new OutputStreamWriter(fos);
BufferedWriter bw = new BufferedWriter(osw);

String line;
while ( (line = br.readLine())!=null ){
bw.append(line);
bw.newLine();
bw.flush();
}

// close
}

關(guān)于流的操作非常多,像包括網(wǎng)絡(luò)通信中、音視頻文件處理、流合并等等

Guava中的IO

關(guān)于IO的內(nèi)容并不復(fù)雜,上面的那些例子在很多工具庫(kù)中基本都會(huì)提供對(duì)應(yīng)的API方便開發(fā)者調(diào)用,今天主要看下Guava IO模塊針對(duì)流的操作提供了什么樣的 封裝

Files

提供對(duì)文件快捷讀寫方法 其中主要提供了ByteSource、ByteSink、CharSource、CharSink 4個(gè)類,分別對(duì)應(yīng)按字節(jié)的讀寫與按字符的讀寫,

/**
* 文件復(fù)制
*/
@Test
public void copy() throws IOException {
File from = new File(root,"from");
File to = new File(root,"to");
Files.copy(from,to);
}

/**
* 文件移動(dòng)
*/
@Test
public void move() throws IOException {
File from = new File(root,"from");
File to = new File(root,"to");
Files.move(from,to);
}

/**
* 按行讀取文件
* @throws IOException
*/
@Test
public void readLines() throws IOException {
File dest = new File(root,"start.bat");
List<String> lines = Files.readLines(dest, Charset.defaultCharset());
lines.forEach(System.out::println);
}

/**
* 寫入文件
* @throws IOException
*/
@Test
public void writeToFile() throws IOException {
File dest = new File(root,"demo.txt");
Files.write("hello world!".getBytes(Charset.defaultCharset()), dest);
}

/**
* 修改文件更新時(shí)間
* @throws IOException
*/
@Test
public void touch() throws IOException {
File dest = new File(root,"demo.txt");
Files.touch(dest);
}

/**
* 文件的零拷貝
* @throws IOException
*/
@Test
public void map() throws IOException, URISyntaxException {
File from = new File(root,"from");
File to = new File(root,"to");
Files.touch(to);

MappedByteBuffer fromBuff = Files.map(from, MapMode.READ_ONLY, 1024);
// =>
FileChannel channel = FileChannel.open(Paths.get(to.toURI()), StandardOpenOption.WRITE);

channel.write(fromBuff);

channel.close();
}

/**
* 讀文件為字節(jié)數(shù)組
* @throws IOException
*/
@Test
public void fileAndBytes() throws IOException {
File dest = new File(root,"start.bat");
ByteSource byteSource = Files.asByteSource(dest);
byte[] bytes = byteSource.read();
System.out.println( bytes );

// 字節(jié)寫入文件,實(shí)現(xiàn)復(fù)制
File target = new File(root, "start2.bat");
ByteSink byteSink = Files.asByteSink(target);
byteSink.write(bytes);
}

@Test
public void wrapper(){
File dest = new File(root,"start.bat");
// 作為字節(jié)讀
Files.asByteSource(dest);
// 作為字節(jié)寫
Files.asByteSink(dest);

// 作為字符讀
Files.asCharSource(dest, Charset.defaultCharset());
// 作為字符寫
Files.asCharSink(dest, Charset.defaultCharset());
}

其他

管道流

PipedOutputStream  PipedInputStream 實(shí)現(xiàn)多線程間的數(shù)據(jù)通信;類似生產(chǎn)消費(fèi)者模式

@Test
public void pipe() throws IOException {
PipedOutputStream pipedOutputStream = new PipedOutputStream();
PipedInputStream pipedInputStream = new PipedInputStream();
pipedOutputStream.connect(pipedInputStream);

new Thread(()->{
while (true){
String date = new Date().toString();
try {
pipedOutputStream.write( date.getBytes(StandardCharsets.UTF_8) );
pipedOutputStream.flush();
TimeUnit.SECONDS.sleep(2);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}).start();

new Thread(()->{
while (true){
byte [] buff = new byte[1024];
try {
int read = pipedInputStream.read(buff);
TimeUnit.SECONDS.sleep(4);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println( new String(buff) );
}
}).start();
}

結(jié)束語(yǔ)

在任何編程語(yǔ)言中,數(shù)據(jù)的IO都是比較常見并相當(dāng)重要的。Guava作為工具型類庫(kù),主要是幫助開發(fā)者封裝常用、重復(fù)的操作,開放出簡(jiǎn)介的API,不僅能讓讓代碼更加整潔, 同時(shí)對(duì)開發(fā)出穩(wěn)健程序也是比不可少的。

責(zé)任編輯:武曉燕 來(lái)源: Java技術(shù)指北
相關(guān)推薦

2009-04-23 08:31:23

微軟鮑爾默收購(gòu)

2017-01-09 12:57:21

Linux

2025-03-25 08:50:00

2025-03-24 00:00:15

2023-11-07 12:56:35

Redis主從復(fù)制

2018-05-14 11:31:02

2018-05-14 17:36:59

2015-12-23 11:32:50

2020-05-13 09:03:14

Python開發(fā)代碼

2021-12-17 07:30:42

排序算法效率

2023-12-26 01:18:11

C代碼CPU主頻

2021-05-02 23:36:23

蘋果手機(jī)國(guó)產(chǎn)

2024-12-03 12:05:57

2023-06-12 11:53:08

數(shù)據(jù)活躍率流失率

2021-03-01 07:59:24

架構(gòu)系統(tǒng)Zachman

2023-11-07 16:21:55

2020-10-16 15:27:04

面試算法

2018-11-14 09:53:48

2018-09-04 11:10:31

Python編程語(yǔ)言面試

2015-08-11 09:18:44

程序員最好
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)