java+输出流++空值_一文搞定Java的输入输出流等常见流
點(diǎn)贊再看,養(yǎng)成習(xí)慣,常用流,多看多練準(zhǔn)沒錯(cuò)!文章較長,建議收藏再看!
1.IO流分析
什么是IO?
I:Input
O:Output
通過IO可以完成對(duì)硬盤的讀和寫。
IO流的分類。
有多種分類方式:
一種方式是:按照列的方向進(jìn)行分類,以內(nèi)存為參照物,往內(nèi)存中去叫做輸入(Input),或者叫做讀(Read).往內(nèi)存中出來叫做輸出(Output),或者叫做寫。
第二種:以讀取數(shù)據(jù)方式的不同進(jìn)行分類:
有的流是按照字節(jié)的方式讀取數(shù)據(jù)。一次讀取一個(gè)字節(jié)byte,等同于讀取8個(gè)二進(jìn)制。這種流是萬能的,什么文件都可以讀取,比如:文本,圖片,視頻…
有的流是按照字符的方式讀取數(shù)據(jù)的,一次讀取一個(gè)字符,這種流是為了方便讀取普通文本文件而存在的,這種流不能讀取:圖片,視頻等文件,連word文件都不能讀取。
例如:假設(shè)文本文件file.txt,采用字符流的話:
a中國bo張三
第一次讀:‘a(chǎn)’字符('a’字符在win系統(tǒng)中占用1個(gè)字節(jié))
第二次讀:’中’字符('中‘字符在win系統(tǒng)中占用2個(gè)字節(jié))
總結(jié)列的分類:
輸入流 ,輸出流。
字節(jié)流,字符流。
Java中char字符占用兩個(gè)字節(jié),但系統(tǒng)中占一個(gè)字節(jié)。
注意:Java中的IO流都已經(jīng)寫好了,我們要會(huì)用就可以了。主要研究怎么new流對(duì)象,調(diào)用哪個(gè)對(duì)象的哪個(gè)方法讀,哪個(gè)方法寫。
2.常用的IO流
Java中所有的流在:java.io.*;
Java IO流的四大家族(都為抽象類):
java.io.InputStream 字節(jié)輸入流
java.io.OutputStream 字節(jié)輸出流
java.io.Reader 字符輸入流。
java.io.Writer 字符輸出流。
Java中以Stream結(jié)尾的都是字節(jié)流,以Reader/Writer結(jié)尾的都是字符流。
所有的流都是可關(guān)閉的,都有close()方法,流是一個(gè)管道,是內(nèi)存和硬盤之間的管道,用完后一定要關(guān)閉,不然會(huì)浪費(fèi)很多資源。
所有的輸出流:都實(shí)現(xiàn)了java.io.Flushiable接口,都是可刷新的,都有flush方法,輸出流最后輸出之后,一定要記得flush(),刷新一下,這個(gè)刷新表示將管道中剩余為輸出的數(shù)據(jù)強(qiáng)行輸出完(清空管道),刷新就是為了清空管道。如果沒有flush()肯能會(huì)造成數(shù)據(jù)丟失。
java.io包下我們需要掌握的16個(gè)流:
//文件
java.io.FileInputStream
java.io.FileOutputStream
java.io.FileReader
java.io.FileWriter
//轉(zhuǎn)換流:(將字節(jié)流轉(zhuǎn)換成字符流)
java.io.InputStreamReader
java.io.OutputStreamWriter
//緩存流
java.io.BufferedReader
java.io.BufferedWriter
java.io.BufferedInputStream
java.io.BufferedOutputStream
數(shù)據(jù)流
java.io.DateInputStream
java.io.DateOutputStream
標(biāo)準(zhǔn)流
java.io.PrintWriter
java.io.PrintStream
對(duì)象流
java.io.ObjectInputStream
java.io.ObjectOutputStream
3.FileInputStream
文件字節(jié)輸入流,萬能的,任何類型的文件都可以采用這個(gè)流來讀。
read()方法讀取一個(gè)字節(jié)的數(shù)據(jù),到文件末尾返回-1。
public class FileInputStreamTest1 {
public static void main(String[] args) {
//創(chuàng)建文件字節(jié)輸入流對(duì)象
FileInputStream fis = null;
{
try {
fis = new FileInputStream("E:\\A/Cat.txt");//雙斜杠代表一個(gè)斜杠或用反斜杠
while (true) {
int readData = fis.read();//讀取到字節(jié)本身
if(readData==-1)
break;
System.out.println(readData);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {//在finally語句塊中確保流一定關(guān)閉
if (fis != null) {//關(guān)閉流的前提是,流不是空
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
read(byte[] t):一次最多讀取t.length個(gè)字節(jié),返回讀取的數(shù)量,注意在數(shù)組中第二次讀的數(shù)據(jù),將第一次讀的數(shù)據(jù)覆蓋,第一次沒有覆蓋的數(shù)據(jù)還在數(shù)組中。如果一個(gè)都沒有讀取到將返回-1。減少內(nèi)存和硬盤的交互。
可以利用String類的轉(zhuǎn)換方法,將byte數(shù)組轉(zhuǎn)換成String.
public class FileInputStreamTest2 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("Chapter1\\Team");
// 準(zhǔn)備一個(gè)byte數(shù)組
byte[] bytes = new byte[4];
int readCount =0;
while ((readCount=fis.read(bytes))!=-1){
System.out.println(new String(bytes,0,readCount));//將數(shù)組轉(zhuǎn)換成字符串
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
IDEA默認(rèn)的當(dāng)前路徑是工程project的根,不是模塊。
available()方法:返回流當(dāng)中剩余的沒有讀到的字節(jié)數(shù)。
skip()方法:跳過幾個(gè)字節(jié)不讀。
public class FileInputStreamTest3 {
public static void main(String[] args) {
FileInputStream pis = null;
try {
pis = new FileInputStream("Chapter1\\Team");
/* int readByte = pis.read();
// 剩余的字節(jié)數(shù)量,其作用為...
System.out.println(pis.available());
// 作用
byte[] bytes= new byte[pis.available()];
// 不需要循環(huán)了,因?yàn)閿?shù)組不能太大所以不適合大文件
int readCount = pis.read(bytes);
System.out.println(new String(bytes));*/
// skip跳過幾個(gè)字節(jié)不讀取
pis.skip(3);
System.out.println(pis.read());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(pis != null){
try {
pis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
4.FileOutputStream
文件字節(jié)輸出流,負(fù)責(zé)寫。
從內(nèi)存到硬盤
write(int b)方法。
write(byte[] b)方法。
write(byte[] b,int off,int len)方法。
public class FileOutputStreamTest1 {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
// 文件不存在會(huì)新建,將源文件清空再寫入
// fos=new FileOutputStream("Chapter1\\Team");
// 以追加的方式寫入
fos = new FileOutputStream("Chapter1\\Team",true);
byte[] bytes = {97,98,99};
String s ="我是一個(gè)中國人";
byte[] aa= s.getBytes();//將字符串轉(zhuǎn)換成byte[]數(shù)組
fos.write(aa);
fos.write(bytes);
// 寫部分
fos.write(bytes,0,1);
// 注意寫完后要刷新
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
5.通過Stream類實(shí)現(xiàn)文件復(fù)制
使用FileInputStream+ FileOutputStream完成文件的拷貝。
適用于任何文件。
練習(xí):
public class Copy1 {
public static void main(String[] args) {
FileInputStream fis =null;
FileOutputStream fos =null;
try {
fis = new FileInputStream("F:\\視頻\\VID_20190425_125038.mp4");
fos = new FileOutputStream("D:\\VID_20190425_125038.mp4");
// 一邊讀一邊寫
byte[] bytes = new byte[1024*1024];//一次最多1M
int readCount =0;
// 讀多少寫多少
while ((readCount=fis.read(bytes))!=-1){
fos.write(bytes,0,readCount);//寫
}
// 記得刷新
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {
if(fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
6.FileReader
文件字符輸入流,只能讀取普通文本。
讀取文本內(nèi)容時(shí),比較方便,快捷。
操作跟FileInputStream類似,將byte數(shù)組,改為char數(shù)組即可,也可以用String的方法將其裝換成字符串形式。
7.FileWriter
文件字符輸出流,寫。
只能輸出普通文本。
例子:
char[] chars = {’我‘,’是‘,'中’}
write(chars)
writer(chars,0,2);
writer("我是中國人“);
不想被清空再創(chuàng)建輸出流對(duì)象是,在文件名后面的第二個(gè)可填項(xiàng),添加true)
public class FileWriterTest1 {
public static void main(String[] args) {
FileWriter out = null;
try {
out = new FileWriter("file",true);
out.write("我是中國人" + "哈哈");
} catch (IOException e) {
e.printStackTrace();
}
finally {
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
通過Writer實(shí)現(xiàn)拷貝普通文件:操作跟Stream一樣,只不過將byte數(shù)組改為Char數(shù)組。
8.BufferedReader緩沖流
帶有緩沖區(qū)的字符輸入流。
使用這個(gè)流的時(shí)候不需要自定義char數(shù)組,或byte數(shù)組,自帶緩沖。
readLine()方法:讀一行。
public class BufferedReaderTest1 {
public static void main(String[] args) {
FileReader reader = null;
try {
reader = new FileReader("file");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//當(dāng)一個(gè)流的構(gòu)造方法需要一個(gè)流的時(shí)候,這個(gè)被傳進(jìn)來的流叫做“節(jié)點(diǎn)流”。
//外部負(fù)責(zé)包裝的這個(gè)流,叫做:包裝流,還有一個(gè)名字叫做:處理流
//當(dāng)前FileReader是節(jié)點(diǎn)流,BufferedReader流叫做包裝流
BufferedReader sc = new BufferedReader(reader);
//對(duì)于包裝流來說,只需要關(guān)閉外層流就行,里面的節(jié)點(diǎn)流會(huì)自動(dòng)關(guān)閉
// readLine方法
String s =null;
while (true) {
try {
if (!((s=sc.readLine())!=null)) break;
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(s);
}
try {
sc.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
練習(xí)二:涉及裝換流
package Day1;
import java.io.*;
public class BufferedReaderTest2 {
public static void main(String[] args) {
FileInputStream in = null;
BufferedReader ge=null;
try {
/*//字節(jié)流
in = new FileInputStream("file");
// 通過轉(zhuǎn)換流轉(zhuǎn)換,in是節(jié)點(diǎn)流,reader是包裝流
InputStreamReader reader = new InputStreamReader(in);
// 這個(gè)構(gòu)造方法只能傳一個(gè)字符流,不能傳字節(jié)流,reader是節(jié)點(diǎn)流
ge = new BufferedReader(reader);*/
String line = null;
// 將以上三個(gè)步驟合并
ge= new BufferedReader(new InputStreamReader(new FileInputStream("file")));
while((line=ge.readLine())!=null){
System.out.println(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(ge!=null){
try {
ge.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
9.DataInputStream和DataOutputStream數(shù)據(jù)流
DataOutputStream這個(gè)流可以將數(shù)據(jù)連同數(shù)據(jù)的類型一并寫入文件。
不是普通文檔。
DateOutputStream寫的文件,只能使用DataInputStream去讀。并且度的時(shí)候需要提前知道寫入的順序。讀的順序要和寫的順序一致,才可以正常取出數(shù)量。
package Day2;
import javax.swing.*;
import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class DateInputStreamTest1 {
public static void main(String[] args) {
DataOutputStream dos = null;
{
try {
dos = new DataOutputStream(new FileOutputStream("Team"));
// 寫數(shù)據(jù)
byte b = 0;
short s = 300;
int i = 322;
long c = 455L;
double d = 3.4;
boolean sex = false;
char f = 'a';
// 寫,包括類型
dos.writeByte(b);
dos.writeShort(s);
dos.writeInt(i);
dos.writeLong(c);
dos.writeDouble(d);
dos.writeBoolean(sex);
dos.writeChar(f);
// 刷新
dos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (dos != null) {
try {
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
10.標(biāo)準(zhǔn)輸出流PrintStream
標(biāo)準(zhǔn)的字節(jié)輸出流,默認(rèn)輸出流,默認(rèn)輸出到控制臺(tái)。
標(biāo)準(zhǔn)輸出流不需要手動(dòng)close關(guān)閉。
存在節(jié)點(diǎn)流,和包裝流。
package Day2;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
public class PrintStreamTest1 {
public static void main(String[] args) throws FileNotFoundException {
System.out.println("Hello World!");
PrintStream print = System.out;
print.println("Oh my god!");
// 可以改變標(biāo)準(zhǔn)輸出流的方向
/* System.gc();
System.currentTimeMillis();
PrintStream print = System.out;
System.exit(0);
System.arraycopy()*/
// 標(biāo)準(zhǔn)輸出流指向file文件,不指向控制臺(tái)
PrintStream printStream=new PrintStream(new FileOutputStream("file"));
// 修改輸出方向
System.setOut(printStream);
System.out.println("Hello SZ");
}
}
練習(xí)2:
package Day2;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
public class PrintStreamTest1 {
public static void main(String[] args) throws FileNotFoundException {
System.out.println("Hello World!");
PrintStream print = System.out;
print.println("Oh my god!");
// 可以改變標(biāo)準(zhǔn)輸出流的方向
/* System.gc();
System.currentTimeMillis();
PrintStream print = System.out;
System.exit(0);
System.arraycopy()*/
// 標(biāo)準(zhǔn)輸出流指向file文件,不指向控制臺(tái)
PrintStream printStream=new PrintStream(new FileOutputStream("file"));
// 修改輸出方向
System.setOut(printStream);
System.out.println("Hello SZ");
}
}
練習(xí)三(記錄日志):
package Day2;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;
public class LogTest1 {
public static void main(String[] args) {
logs("成功完成了日志的代碼!");
logs("完成Java的學(xué)習(xí)!");
logs("登入系統(tǒng)成功!");
logs("你向某某支付XXX錢!");
logs("你收到來著某某的XXXXXXXX人民幣!");
}
public static void logs (String s){
// 指向日志文件
PrintStream log =null;
try {
log = new PrintStream(new FileOutputStream("log.txt",true));
// 改變輸出方向
System.setOut(log);
// 獲取當(dāng)前時(shí)間
Date nowTime = new Date();
SimpleDateFormat ss = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
String times=ss.format(nowTime);
System.out.println(times+" "+s);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//不需要關(guān)閉
}
}
11.File類
File類和四大家族沒有關(guān)系,所以不能完成文件的讀取。
File對(duì)象代表什么?
文件和目錄路徑名的抽象表示形式。
C:\Drivers 這是一個(gè)File對(duì)象。
C:\Drevers\reader.txt 也是一個(gè)File對(duì)象。
File只是一個(gè)路徑名的表現(xiàn)形式。
FIle的常用方法:
以下通過練習(xí)來說明
package Day2;
import java.io.File;
import java.io.IOException;
public class FileTest1 {
public static void main(String[] args) {
// 創(chuàng)建一個(gè)File對(duì)象
File f1 = new File("D:\\tt.txt");
// 判斷文件是否存在
System.out.println(f1.exists());
// 1.如果D:\tt.txt不存在,以文件的形式創(chuàng)建
/* if(!f1.exists()){
try {
f1.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}*/
// 2.如果不存在,以目錄的形式創(chuàng)建
/*if(!f1.exists()){
f1.mkdir();
}*/
// 3.以多重目錄新建
/* File f2 =new File("D:\\xi\\c\\z\\a");
if(!f2.exists()){
f2.mkdirs();
}*/
// 4.獲取文件的父路徑
File f3 = new File("D:\\WeChat\\locales");
String parentPath = f3.getParent();
System.out.println(parentPath);
// 5.獲取絕對(duì)路徑
File f4 = new File("Team");
System.out.println(f4.getAbsolutePath());
}
}
練習(xí)2:
package Day2;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
public class FileTest2 {
public static void main(String[] args) {
File f1 = new File("D:\\resources");
// 6.獲取文件名
System.out.println(f1.getName());
// 7.判斷是否時(shí)一個(gè)目錄
System.out.println(f1.isDirectory());
// 8.判斷是否是一個(gè)文件
System.out.println(f1.isFile());
// 9.獲去文件最后一次修改時(shí)間
long haoMiao = f1.lastModified();
// 將總毫秒樹轉(zhuǎn)換成日期
Date time = new Date(haoMiao);
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
System.out.println(sd.format(time));
// 10.獲取文件大小,字節(jié)
System.out.println(f1.length());
// 11.獲取當(dāng)前目錄下所有的子文件
File[] files = f1.listFiles();
for(File file :files){
System.out.println(file);
}
}
}
12.拷貝目錄練習(xí)(重點(diǎn))
package Day2;
import java.io.*;
public class CopyContent1 {
public static void main(String[] args) {
// 拷貝源
File srcFile = new File("F:\\QQ");
// 拷貝目標(biāo)(放哪里)
File destFile = new File("D:\\");
// 調(diào)用方法
copyDir(srcFile,destFile);
}
private static void copyDir(File srcFile, File destFile) {
if(srcFile.isFile()){//如果是文件遞歸結(jié)束
/*是文件就拷貝,一邊讀,一邊寫*/
FileInputStream in = null;
FileOutputStream out = null;
try {
//讀
in = new FileInputStream(srcFile);
//寫
String path = (destFile.getAbsolutePath().endsWith("\\") ? destFile.getAbsolutePath() : destFile.getAbsolutePath() + "\\" )+srcFile.getAbsolutePath().substring(3);
out = new FileOutputStream(path);
byte[] bytes = new byte[1024*1024];
int readCount =0;
while((readCount=in.read(bytes))!=-1){
out.write(bytes,0,readCount);//讀多少寫多少
}
out.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(in!=null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return;
}
// 獲取源的子目錄
File[] files= srcFile.listFiles();
for(File file :files){
if(file.isDirectory()) {
// 獲取所有文件的絕對(duì)路徑
// System.out.println(file.getAbsolutePath());
// 新建目標(biāo),對(duì)應(yīng)的目錄,將源目錄除根目錄外,其余加到目標(biāo)目錄后面
String srcDir
總結(jié)
以上是生活随笔為你收集整理的java+输出流++空值_一文搞定Java的输入输出流等常见流的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python避坑指南_Linux下Pyt
- 下一篇: 关于计算机的英语演讲稿三分钟,以计算机为