第19天 IO流

概述

I(input):输入
O(output): 输出
IO流分为字符流和字节流
字符流是只能操作纯文本的文件,以字符(2个字节)为单位进行数据读写的流
字节流可以操作任意类型的文件,以字节为单位进行数据读写的流

| | 字符流 | 字节流
|输入流| 字符输入流(reader)|| 字节输入流(InputStream) 超类
|输出流| 字符输出流(writer) || 字节输出流 (OutputStream)

进到程序中的内容叫输入
从程序发出的内容叫输出,
输入流:从文件中读取内容输入到程序中,也就是读文件
输出流:将程序中的数据内容输出到文件中。也就是写文件
以程序为中心

上面的顶级父类都是抽象类,不能直接使用

字符输入输出流

抽象基类 : Reader、Writer

是字符输入输出流的超类
以字符为单位读写数据,一次处理一个unicode
字符流的底层是字节流

访问文件:FileReader、FileWriter

FileWriter

主要用于将文本内容写入到文本文件

//创建一个新文件,如果没有,直接创建。如果有,替换为这个。只能创建一个文件,不能创建文件夹
        FileWriter fileWriter = new FileWriter("D:\\a.txt");

        String str = "abcdefg";
        //fileWriter.write((可以写数字或者单个的字符,数字会转换成对应的阿斯克码))
		//在指定字符数组中从下标1开始的3个字符写入此文件的输出流
        fileWriter.write(str,1,3);

        //冲刷缓冲区:fileWriter.flush()
        //内存中的数据并不是直接到文件中,而是先到缓冲区,等待积累部分后再到文件中
        //如果不冲刷,则会和内存一起消失,不会到文件中

        //关闭流,关闭流时会自动重刷一次缓冲区
        fileWriter.close();
        //将这个流对象标记为垃圾对象
        fileWriter = null;

FileReader

主要用于从文本文件读取文本数据内容

public static void main(String[] args) throws IOException {
//创建流对象,指向要读取的文件
        FileReader reader = new FileReader("D:\\abc.txt");
        //创建字符数组作为缓冲区
        char[] cs = new char[5];
        int len;
        //read是读取单个字符的数据并返回,返回-1表示读取到末尾
        while((len = reader.read(cs)) != -1){
            System.out.println(len);
            System.out.println(new String(cs,0,len));
        }
        reader.close();
    }
}


缓冲流:BufferedWriter,BufferedReader。高级流:在其他流上添加就可以加入额外的功能

BufferedWriter

用于写入单个字符,字符数组及字符串到输出流中。

BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("一个路径"))                        
BufferedReader

用于从输入流中读取单个字符,字符数组以及字符串

BufferedReader bufferedreader = new BufferedWriter(new FileReader("一个路径"))


转换流 InputStreamReader,OutputStreamReader

InputStreamReader《FileInPutStream》

字符输入流
主要实现从字节流到字符流的转换

 InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("D:\\test2.txt"),"utf-8");

OutputStreamWriter 《FileOutPutStream》

字符输出流
实现字符流到字节流的转换

FileOutputStream fos = new FileOutputStream("输出到哪一个文件夹")
OutputStreamWriter osw = new OutputStreamWriter(fos,StandardCharsets指定字符集)

osw.write("要写的字符串") //写入文件中
osw.close();

字节输入输出流

inputstream、outputstream是字节输入输出的超类

(重点)访问文件 FileInPutStream,FileOutPutStream

FileInPutStream

低级流

在程序中以字节流的方式读取图像数据等

有块读取操作,一次读取一个byte[]数组,数组自己规定读缩少字节。注意 读的字节不足时,前面只是覆盖,后边还是原字节

FileIutputStream fis = new FilwIutputStream("加入文件路径名"File file文件);/

int d = fis.read();//每次读取一个字节,也就是8位二进制,每次调用read()后自动移动8位以便读取后边的值,返回到int型是32位所以前24位自动补零
int d = fis.read();//多次读取后没有值了返回-1

int d;

while((d = fis.read())!=-1){fos.write(d);}//复制文件.每次传输8位,直到传输完成返回-1

//使用块读
byte[] data = new byte[1024*10];//默认初始为0
int d;//记录每次读写的数据量,如果读完了则返回-1
while((d=fis.read(data)) != -1){ // 返回读取的字节个数给d
fos.write(data);
}
或者 while((d=fis,read(data)) != -1){fos.write(data,0,d)}//给它设定范围,仅复制从下标0开始d个(d代表长度)有效数值,不会在最后一次也赋值全部的byte数据


使用块读字符串
//1.读取文件中的所有的字节
File file = new File("fos.txt");
long len = file.length();

FileInputStream fis = new FileInputStream(File);
byte[] data =  new byte[(int)len];
fis.read(data);//将所有字节读入到data数组中


//2.将这些字节转换为字符串

String line = new String(data,StandardCharsets.UTF-8);
sout(line);
fis.close();


FileOutPutStream

将图像数据之类的原始字节流写入到文件中
gbk:国标编码
Unicode:国际每个字符都有独特的编码,通过2个字节包含,65536个组合包含世界上的常用字符,但日常传输不使用,因为没有分隔符计算机不知道如何分1010看
UTF-8 :有分隔符的Unicode,每个中文字变成了三个字节

//创建了一个流
FileOutputStream fos = new FilwOutputStream("加入文件路径名"File file文件);//文件名不存在会自动创建

fos.write(2)//2是int型,有32位,但是write只会写低8位,一个字节。输出时将第八位对应的阿斯克码值显示出来。这个方法是写入字节数据的。括号内不能写Stirng类型的,的,可以使用.getbytes()将字符串转为字节数组

fos.close();//最终操作后关闭

// 1111 1111 代表-1 第一个是符号位,后边的1代表是负数里最大的。第一位是符号位代表补码
// 1000 0000  代表-127 ,后边的0代表是负数里最小的

//使用块写字符串
String line = "怎么办呢";
byte[] data = line.getBytes(StandardCharsets.UTF-8);

//覆盖模式 :默认不写则为false,覆盖模式若原文件存在重新运行时原来的数据不保留,直接先清空再执行新的
//追加模式:FileOutputStream fos = new FilwOutputStream("加入文件路径名"或File file文件,ture);,加入true说明是追加模式,追加模式下在文件运行时不会清空文件内容而是会保留

fos.write(data);
sout("写入完毕");

fos.close();



(重点)缓冲流 BufferInputStream,BufferOutPutStream。高级流,在低级流之上,给低级流添加功能

功能:在流链接中加块读写效率。底层是一次传8k的数据
缓冲流是最接近低级流的高级流

FileInputStream fis = new FileInputStream("路径");
BufferedInputStream bis = new BufferedInputStream(fis)

bis.read()
bos.write()

BufferInputStream 输入流

描述缓冲输入流

FileOutputStream fos = new FileOutputStream("路径");
BufferedOutputStream bos = new BufferedOutputStream(fis)

BufferOutputStream 输出流

主要用于描述缓冲输出流,并不是每次调用 write() 都会立即写入到磁盘,而是先缓冲到内存中。当缓冲区满了或者调用 flush() 方法时,才会将数据真正写入到文件中,这样可以减少与磁盘的交互次数,提高写入效率。
但这样会有写缓冲问题,因为如果bos的数组没有装满,是不会送到cpu,所以在close()的时候,数据也丢失了,并没有送到地方

bos.flush();//强制将缓冲流的全部字节一次性写出

所有字节输出流都有flush方法,比缓冲流更高级的流调用flush()方法时的目的是,调用更低一级的flush流,直到调用到bos.flush()

(重点)对象流 ObjectInputStream,ObjectOutPutStream

作用

ObjectInputStream

java.io.ObjectInputStream类主要用于从输入流中一次性将对象整体读取出来。
将对象转化为可以保存的字节
所谓反序列化主要指将有效组织的字节序列恢复为一个对象及相关信息的转化过程。

FileIutputStream fis = new FileIutputStream("路径名")
ObjectIutputStream ois = new ObjectIutputStream(fis)

类 类名 = (类名)ois.readObject();//向下造型
sout(类名)

transient 关键字
当一个属性被transient关键字修饰后,在进行序列化时转换出来的字节是不包含该属性的
可以节省传输时间

ObjectOutPutStream

java.io.ObjectOutputStream类主要用于将一个对象的所有内容整体写入到输出流中。
只能将支持 java.io.Serializable 接口的对象写入流中。
类通过实现 java.io.Serializable 接口以启用其序列化功能。
Serializable是签名接口,里面是空的,没有要实现的方法
所谓序列化主要指将一个对象需要存储的相关信息有效组织成字节序列的转化过程。


FileOutputStream fos = new FileOutputStream("路径名")
ObjectOutputStream oos = new ObjectOutputStream(fos)
oos.writeObject(类的名字);//将给定的对象转换为字节,然后通过其连接的流将字节写出.这个类必须实现Serializable接口。否则报错

oos.close();

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
java.net.SocketException: Connection reset at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:323) at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350) at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803) at java.base/java.net.Socket$SocketInputStream.read(Socket.java:966) at java.base/java.io.InputStream.read(InputStream.java:218) at SSocket/com.cuc.socketfile.FileClinet.<init>(FileClinet.java:19) at SSocket/com.cuc.socketfile.FileClinet.main(FileClinet.java:40)网络没问题但就是连接出错会不会是代码问题以下第一个是我的服务器代码,第二个是我的客户端代码package com.cuc.socketfile; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class FileServer { ServerSocket server; Socket socket; public FileServer() { FileInputStream file = null; try { server = new ServerSocket(6634); socket = server.accept(); OutputStream out = socket.getOutputStream(); file = new FileInputStream("src/s.txt"); byte buffer[] = new byte[1024]; int len = 0; while ((len=file.read(buffer)) != -1) { out.write(buffer, 0, len); out.flush(); } socket.shutdownInput(); } catch (IOException e) { e.printStackTrace(); }finally { if (file != null) { try { file.close(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } } public static void main(String[] args) { new FileServer(); } }客户端代码如下package com.cuc.socketfile; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.Socket; import java.net.UnknownHostException; public class FileClinet { Socket socket; public FileClinet() { FileOutputStream file = null; try { socket = new Socket("127.0.0.1", 6634); InputStream in = socket.getInputStream(); file = new FileOutputStream("5237.file"); byte buffer[] = new byte[1024]; int len = 0; while (((len = in.read(buffer)) != -1)) { file.write(buffer, 0, len); file.flush(); } } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if (file == null) { try { file.close(); socket.close(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } } public static void main(String[] args) { new FileClinet(); } }
05-11

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值