首页 > Windows开发 > 详细

网络IO-IO操作的常用API

时间:2020-05-12 23:15:04      阅读:71      评论:0      收藏:0      [点我收藏+]

本地磁盘文件操作之File

File类简介

  • File类是Java中为文件进行创建、删除、重命名、移动等操作而设计的一个类。它是属于Java.io包下的类。

File类基本操作

  • - File(File parent,String child): 根据parent抽象路径名和child路径名字符串创建一个新的File实例

  • - File(String pathname): 将指定路径名转化为抽象路径名创建一个新的File实例

  • - File(String parent,String child):根据parent路径名和child路径名创建一个File 实例

  • - File(URI uri): 指定URI转化为抽象路径名

基于文件的字节输入输出流实战

{
//根据用户端输入的路径进行目录的遍历
public static void main(String[] args) throws IOException {
InputStreamReader reader =new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(reader);
try {
String path = bufferedReader.readLine();
File file = new File(path);
if (file.isDirectory()&&file.exists()){
//去遍历这个目录下所有的子目录
fileList(file);
}else{
System.out.println("文件路径输入错误");
}
} catch (IOException e) {
e.printStackTrace();
}finally {
bufferedReader.close();
reader.close();
}
}

private static void fileList(File filePath){
File[] files = filePath.listFiles();
if (files !=null){
for (int i =0;i <files.length;i++){
if (files[i].isFile()){
//输出具体的文件名
System.out.println(files[i].getName());
}else{
//如果是一个目录
fileList(files[i]);
}
}
}
}
}

 

深入浅出read方法

Read输入

当读取不到数据的时候read()返回值为-1

为了防止提高性能使用baye[]数据进行存储数据,每次读取数据长度为数组长度,避免每次都进行交互,数据长度应该适当,长度越大占用内存空间越大

public class ReadDemo {
    public staticvoid main(String[] args) {
        try {
            FileInputStreamfileInputStream =new FileInputStream("F:/test.txt");
            int i = 0;
            byte[] buffer = new byte[3];
            //读取指定目录的字节,如果read方法没有输入,会阻塞
            while ((i =fileInputStream.read(buffer)) != -1){
               //fileOutputStream.write(i);
                System.out.print(new String(buffer,0,i));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

基于内存的字节输入输出流实战

使用ByteArrayInputStream()方法进行操作

public class MemoryDemo {
    static String str = "helloworld";

    public static void main(String[] args){
        //从内存种读取数据
        ByteArrayInputStreaminputStream = new ByteArrayInputStream(str.getBytes());
        //写出到内存种
        ByteArrayOutputStreamoutputStream = new ByteArrayOutputStream();
        int i = 0;
        while ((i =inputStream.read()) != -1){
            char c = (char)i;
            outputStream.write(Character.toUpperCase(c));
        }
        System.out.println(outputStream.toString());
    }
}

基于缓冲流的输入输出实战

  • 缓冲流:缓冲流是带缓冲区的处理流,它会提供一个缓冲区,缓冲区的作用的主要 目的是:避免每次和硬盘打交道,能够提高输入/输出的执行效率。分别为BufferedInputStream()与BufferedOutputStream()

 

public class BufferedDemo {
public static void main(String[] args) {
try(BufferedInputStream bufferedInputStream =new BufferedInputStream
(new FileInputStream("F:/test.txt"));
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream
(new FileOutputStream("F:/tes.txt"))) {
int len = 0;
byte[] bys = new byte[1024];
while ((len = bufferedInputStream.read(bys)) != -1){
System.out.println(new String(bys,0,len));
bufferedOutputStream.write(bys,0,len);
bufferedOutputStream.flush();
}
}catch (Exception e){

}
}

}

普通流的输入输出与缓冲流的输入输出运行速度比较

public class BudderedCopyDemo {
private static File fileSource =
new File("E:/Test001.zip");
private static File fileTarget =
new File("E:/Test001_cp.zip");
public void copyWithNormal(){
try(FileInputStream fileInputStream =
new FileInputStream(fileSource);
FileOutputStream fileOutputStream =
new FileOutputStream(fileTarget)) {
int i = 0;
byte[] bytes = new byte[1024];
while ( (i = fileInputStream.read(bytes)) != -1){
fileOutputStream.write(bytes);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void copyWithBuffered(){
try(FileInputStream fileInputStream =
new FileInputStream(fileSource);
FileOutputStream fileOutputStream =
new FileOutputStream(fileTarget);
BufferedInputStream bufferedInputStream =
new BufferedInputStream(fileInputStream);
BufferedOutputStream bufferedOutputStream =
new BufferedOutputStream(fileOutputStream)) {
int i = 0;
byte[] bytes = new byte[1024];
while ( (i = bufferedInputStream.read(bytes)) != -1){
bufferedOutputStream.write(bytes);
}
} catch (Exception e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
BudderedCopyDemo budderedCopyDemo =
new BudderedCopyDemo();
long stra = System.currentTimeMillis();
budderedCopyDemo.copyWithNormal();
long end =System.currentTimeMillis();
System.out.println("普通方式进行读取:"+(end-stra));
stra = System.currentTimeMillis();
budderedCopyDemo.copyWithBuffered();
end =System.currentTimeMillis();
System.out.println("缓冲流方式进行读取:"+(end-stra));
}
}

 

运行结果:

技术分享图片

详解Flush方法


public class FlushDemo {
public static void main(String[] args) throws Exception {
BufferedOutputStream bufferedOutputStream =
new BufferedOutputStream(new FileOutputStream("E:/liyao.txt"));
bufferedOutputStream.write("hello wrld".getBytes());
}
}

 

当前代码复制文件,代码运行完成文件并没有数据写入

技术分享图片

 

public class FlushDemo {
public static void main(String[] args) throws Exception {
BufferedOutputStream bufferedOutputStream =
new BufferedOutputStream(new FileOutputStream("E:/liyao.txt"));
bufferedOutputStream.write("hello wrld".getBytes());
bufferedOutputStream.flush();
}
}

 

增加flush()方法,代码运行完成文件数据写入成功

技术分享图片

因为缓存区大小默认为8kb但是我们现在的文件没有达到8kb所有不会进行磁盘刷新。flush()方法做了一个类似与刷盘的操作,如果使用 try/ catch相当于触发了close()方法,close()也会触发flush()进行一个刷盘操作

基于文件的字符输入输出流实战

public class ByteReadDemo {
    public staticvoid main(String[] args) {
        try(FileInputStreamfileInputStream = new FileInputStream("E:/liyao.txt")) {
        int len = 0;
        while ((len =fileInputStream.read()) != -1){
            System.out.print((char)len);
        }
        }catch (Exception e){
            e.getStackTrace();
        }
    }
}

输出

因为read()一次读取一个字节,而汉字一次4个字节所以就会出现乱码。解决办法之一增加byte[]数据进行数据存储让它一次性提交完成。从而避免乱码。注意:这里的文件格式为UTF-8

字节流:

public class ByteReadDemo {
    public staticvoid main(String[] args) {
        try(FileInputStreamfileInputStream = new FileInputStream("E:/liyao.txt")) {
        int len = 0;
        byte[] by=new byte[1024];
        while ((len =fileInputStream.read(by)) != -1){
            System.out.print(new String(by,0,len));
       }
        }catch (Exception e){
            e.getStackTrace();
        }
    }
}

输出

技术分享图片

 

字符流:

public class ReaderWriterDemo {
    public staticvoid main(String[] args) {
        try(FileReaderfileReader = new FileReader("E:/liyao.txt")){
            int len = 0;
            char[] chars =new char[1024];
            while ((len =fileReader.read(chars))!= -1){
                System.out.println(new String(chars,0,len));
            }
        }catch (Exception e){
            e.getStackTrace();
        }
    }
}

输出:

技术分享图片

 

字节流与字符流的转换输出

public class ConvertDemo {
    public staticvoid main(String[] args) {
        try(BufferedInputStreaminputStream =new BufferedInputStream(new FileInputStream("E:/liyao.txt")) ){
            InputStreamReaderinputStreamReader = new InputStreamReader(inputStream,"UTF-8");
            BufferedReaderbufferedReader = new BufferedReader(inputStreamReader);
            System.out.println(bufferedReader.readLine());//读取一行数据
            String str =bufferedReader.readLine();
            //字符转换流
            OutputStreamWriteroutputStreamWriter = new OutputStreamWriter(new FileOutputStream("E:/liyao_cp.txt"),"UTF-8");
            BufferedWriterbufferedWriter =new BufferedWriter(outputStreamWriter);
            bufferedWriter.write("1234");
            bufferedWriter.flush();
        }catch (Exception e){
        }
    }
}

序列化和反序列化

  • 序列化:序列化是把对象的状态信息转化为可存储或传输的形式过程,也就是把对 象转化为字节序列的过程称为对象的序列化

  • 反序列化:反序列化是序列化的逆向过程,把字节数组反序列化为对象,把字节序列 恢复为对象的过程成为对象的反序列化

 

序列化DEMO

创建user对象

public class User implements Serializable {
private String name;
private long age;
public User(String name, long age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public long getAge() {
return age;
}

public void setAge(long age) {
this.age = age;
}

@Override
public String toString() {
return "TestDemo{" +
"name=‘" + name + ‘\‘‘ +
", age=" + age +
‘}‘;
}
}

 

实现序列化与反序列化

 

public class ObjectDemo {
public static void main(String[] args) {
//ObjectInputStream
//实现对象序列化
User user = new User("Tom",18);//存储到内存中
try(ObjectOutputStream objectOutputStream = new ObjectOutputStream
(new FileOutputStream("E:/user111"))){
objectOutputStream.writeObject(user);
}catch (Exception e){
e.printStackTrace();
}
//ObjectInputStream
//反序列化
try(ObjectInputStream objectInputStream = new ObjectInputStream
(new FileInputStream("E:/user111"));) {
user = (User) objectInputStream.readObject();
System.out.println(user);
}catch (Exception e){
}
}
}

 

深入分析IO的底层原理

IO流的整个体系与交互过程逻辑图

技术分享图片

 

Read()把数据从内核缓冲区复制到进程的用户空间的缓冲区

Write()把进程的缓冲区复制到内核缓冲区在通过磁盘控制器写入到本地磁盘

所有操作是跟缓冲区交互,缓冲区满了在写磁盘,写入的数据到缓冲区没有同步到磁盘。那么当服务器宕机的时候,缓冲区的数据就有可能会丢失

缓冲IO的优点:

它在一定程度分离了用户空间与内核空间保护了系统本身的一个运行安全

它可以减少与磁盘的交互次数,从而提升性能

缓冲IO的缺点:

不能在应用程序直接与磁盘进行数据传输,需要进行多次数据拷贝带来CUP的性能损耗,内存损耗

网络IO-IO操作的常用API

原文:https://www.cnblogs.com/liyaolog/p/12879470.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!