java+输出流++空值_一文搞定Java的输入输出流等常见流

点赞再看,养成习惯,常用流,多看多练准没错!文章较长,建议收藏再看!

1.IO流分析

什么是IO?

I:Input

O:Output

通过IO可以完成对硬盘的读和写。

0216b92189cc73e3606ec0e44b0a8457.png

IO流的分类。

有多种分类方式:

一种方式是:按照列的方向进行分类,以内存为参照物,往内存中去叫做输入(Input),或者叫做读(Read).往内存中出来叫做输出(Output),或者叫做写。

第二种:以读取数据方式的不同进行分类:

有的流是按照字节的方式读取数据。一次读取一个字节byte,等同于读取8个二进制。这种流是万能的,什么文件都可以读取,比如:文本,图片,视频…

有的流是按照字符的方式读取数据的,一次读取一个字符,这种流是为了方便读取普通文本文件而存在的,这种流不能读取:图片,视频等文件,连word文件都不能读取。

例如:假设文本文件file.txt,采用字符流的话:

a中国bo张三

第一次读:‘a’字符('a’字符在win系统中占用1个字节)

第二次读:’中’字符('中‘字符在win系统中占用2个字节)

总结列的分类:

输入流 ,输出流。

字节流,字符流。

Java中char字符占用两个字节,但系统中占一个字节。

注意:Java中的IO流都已经写好了,我们要会用就可以了。主要研究怎么new流对象,调用哪个对象的哪个方法读,哪个方法写。

2.常用的IO流

Java中所有的流在:java.io.*;

Java IO流的四大家族(都为抽象类):

java.io.InputStream 字节输入流

java.io.OutputStream 字节输出流

java.io.Reader 字符输入流。

java.io.Writer 字符输出流。

Java中以Stream结尾的都是字节流,以Reader/Writer结尾的都是字符流。

所有的流都是可关闭的,都有close()方法,流是一个管道,是内存和硬盘之间的管道,用完后一定要关闭,不然会浪费很多资源。

所有的输出流:都实现了java.io.Flushiable接口,都是可刷新的,都有flush方法,输出流最后输出之后,一定要记得flush(),刷新一下,这个刷新表示将管道中剩余为输出的数据强行输出完(清空管道),刷新就是为了清空管道。如果没有flush()肯能会造成数据丢失。

java.io包下我们需要掌握的16个流:

//文件

java.io.FileInputStream

java.io.FileOutputStream

java.io.FileReader

java.io.FileWriter

//转换流:(将字节流转换成字符流)

java.io.InputStreamReader

java.io.OutputStreamWriter

//缓存流

java.io.BufferedReader

java.io.BufferedWriter

java.io.BufferedInputStream

java.io.BufferedOutputStream

数据流

java.io.DateInputStream

java.io.DateOutputStream

标准流

java.io.PrintWriter

java.io.PrintStream

对象流

java.io.ObjectInputStream

java.io.ObjectOutputStream

3.FileInputStream

文件字节输入流,万能的,任何类型的文件都可以采用这个流来读。

read()方法读取一个字节的数据,到文件末尾返回-1。

public class FileInputStreamTest1 {

public static void main(String[] args) {

//创建文件字节输入流对象

FileInputStream fis = null;

{

try {

fis = new FileInputStream("E:\\A/Cat.txt");//双斜杠代表一个斜杠或用反斜杠

while (true) {

int readData = fis.read();//读取到字节本身

if(readData==-1)

break;

System.out.println(readData);

}

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} finally {//在finally语句块中确保流一定关闭

if (fis != null) {//关闭流的前提是,流不是空

try {

fis.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

}

}

read(byte[] t):一次最多读取t.length个字节,返回读取的数量,注意在数组中第二次读的数据,将第一次读的数据覆盖,第一次没有覆盖的数据还在数组中。如果一个都没有读取到将返回-1。减少内存和硬盘的交互。

可以利用String类的转换方法,将byte数组转换成String.

public class FileInputStreamTest2 {

public static void main(String[] args) {

FileInputStream fis = null;

try {

fis = new FileInputStream("Chapter1\\Team");

// 准备一个byte数组

byte[] bytes = new byte[4];

int readCount =0;

while ((readCount=fis.read(bytes))!=-1){

System.out.println(new String(bytes,0,readCount));//将数组转换成字符串

}

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} finally {

if(fis!=null){

try {

fis.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

}

IDEA默认的当前路径是工程project的根,不是模块。

available()方法:返回流当中剩余的没有读到的字节数。

skip()方法:跳过几个字节不读。

public class FileInputStreamTest3 {

public static void main(String[] args) {

FileInputStream pis = null;

try {

pis = new FileInputStream("Chapter1\\Team");

/* int readByte = pis.read();

// 剩余的字节数量,其作用为...

System.out.println(pis.available());

// 作用

byte[] bytes= new byte[pis.available()];

// 不需要循环了,因为数组不能太大所以不适合大文件

int readCount = pis.read(bytes);

System.out.println(new String(bytes));*/

// skip跳过几个字节不读取

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

文件字节输出流,负责写。

从内存到硬盘

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 {

// 文件不存在会新建,将源文件清空再写入

// fos=new FileOutputStream("Chapter1\\Team");

// 以追加的方式写入

fos = new FileOutputStream("Chapter1\\Team",true);

byte[] bytes = {97,98,99};

String s ="我是一个中国人";

byte[] aa= s.getBytes();//将字符串转换成byte[]数组

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类实现文件复制

使用FileInputStream+ FileOutputStream完成文件的拷贝。

适用于任何文件。

练习:

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

文件字符输入流,只能读取普通文本。

读取文本内容时,比较方便,快捷。

操作跟FileInputStream类似,将byte数组,改为char数组即可,也可以用String的方法将其装换成字符串形式。

7.FileWriter

文件字符输出流,写。

只能输出普通文本。

例子:

char[] chars = {’我‘,’是‘,'中’}

write(chars)

writer(chars,0,2);

writer("我是中国人“);

不想被清空再创建输出流对象是,在文件名后面的第二个可填项,添加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实现拷贝普通文件:操作跟Stream一样,只不过将byte数组改为Char数组。

8.BufferedReader缓冲流

带有缓冲区的字符输入流。

使用这个流的时候不需要自定义char数组,或byte数组,自带缓冲。

readLine()方法:读一行。

public class BufferedReaderTest1 {

public static void main(String[] args) {

FileReader reader = null;

try {

reader = new FileReader("file");

} catch (FileNotFoundException e) {

e.printStackTrace();

}

//当一个流的构造方法需要一个流的时候,这个被传进来的流叫做“节点流”。

//外部负责包装的这个流,叫做:包装流,还有一个名字叫做:处理流

//当前FileReader是节点流,BufferedReader流叫做包装流

BufferedReader sc = new BufferedReader(reader);

//对于包装流来说,只需要关闭外层流就行,里面的节点流会自动关闭

// 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();

}

}

}

练习二:涉及装换流

package Day1;

import java.io.*;

public class BufferedReaderTest2 {

public static void main(String[] args) {

FileInputStream in = null;

BufferedReader ge=null;

try {

/*//字节流

in = new FileInputStream("file");

// 通过转换流转换,in是节点流,reader是包装流

InputStreamReader reader = new InputStreamReader(in);

// 这个构造方法只能传一个字符流,不能传字节流,reader是节点流

ge = new BufferedReader(reader);*/

String line = null;

// 将以上三个步骤合并

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数据流

DataOutputStream这个流可以将数据连同数据的类型一并写入文件。

不是普通文档。

DateOutputStream写的文件,只能使用DataInputStream去读。并且度的时候需要提前知道写入的顺序。读的顺序要和写的顺序一致,才可以正常取出数量。

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"));

// 写数据

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.标准输出流PrintStream

标准的字节输出流,默认输出流,默认输出到控制台。

标准输出流不需要手动close关闭。

存在节点流,和包装流。

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!");

// 可以改变标准输出流的方向

/* System.gc();

System.currentTimeMillis();

PrintStream print = System.out;

System.exit(0);

System.arraycopy()*/

// 标准输出流指向file文件,不指向控制台

PrintStream printStream=new PrintStream(new FileOutputStream("file"));

// 修改输出方向

System.setOut(printStream);

System.out.println("Hello SZ");

}

}

练习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!");

// 可以改变标准输出流的方向

/* System.gc();

System.currentTimeMillis();

PrintStream print = System.out;

System.exit(0);

System.arraycopy()*/

// 标准输出流指向file文件,不指向控制台

PrintStream printStream=new PrintStream(new FileOutputStream("file"));

// 修改输出方向

System.setOut(printStream);

System.out.println("Hello SZ");

}

}

练习三(记录日志):

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的学习!");

logs("登入系统成功!");

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);

// 获取当前时间

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();

}

//不需要关闭

}

}

11.File类

File类和四大家族没有关系,所以不能完成文件的读取。

File对象代表什么?

文件和目录路径名的抽象表示形式。

C:\Drivers 这是一个File对象。

C:\Drevers\reader.txt 也是一个File对象。

File只是一个路径名的表现形式。

FIle的常用方法:

以下通过练习来说明

package Day2;

import java.io.File;

import java.io.IOException;

public class FileTest1 {

public static void main(String[] args) {

// 创建一个File对象

File f1 = new File("D:\\tt.txt");

// 判断文件是否存在

System.out.println(f1.exists());

// 1.如果D:\tt.txt不存在,以文件的形式创建

/* if(!f1.exists()){

try {

f1.createNewFile();

} catch (IOException e) {

e.printStackTrace();

}

}*/

// 2.如果不存在,以目录的形式创建

/*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.获取绝对路径

File f4 = new File("Team");

System.out.println(f4.getAbsolutePath());

}

}

练习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.判断是否时一个目录

System.out.println(f1.isDirectory());

// 8.判断是否是一个文件

System.out.println(f1.isFile());

// 9.获去文件最后一次修改时间

long haoMiao = f1.lastModified();

// 将总毫秒树转换成日期

Date time = new Date(haoMiao);

SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");

System.out.println(sd.format(time));

// 10.获取文件大小,字节

System.out.println(f1.length());

// 11.获取当前目录下所有的子文件

File[] files = f1.listFiles();

for(File file :files){

System.out.println(file);

}

}

}

12.拷贝目录练习(重点)

package Day2;

import java.io.*;

public class CopyContent1 {

public static void main(String[] args) {

// 拷贝源

File srcFile = new File("F:\\QQ");

// 拷贝目标(放哪里)

File destFile = new File("D:\\");

// 调用方法

copyDir(srcFile,destFile);

}

private static void copyDir(File srcFile, File destFile) {

if(srcFile.isFile()){//如果是文件递归结束

/*是文件就拷贝,一边读,一边写*/

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()) {

// 获取所有文件的绝对路径

// System.out.println(file.getAbsolutePath());

// 新建目标,对应的目录,将源目录除根目录外,其余加到目标目录后面

String srcDir

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值