Java-流和IO

news2024/9/21 12:40:23

文章目录

      • InputStream
        • FileInputStream
          • 常用方法详情
          • 代码示例
        • BufferInputStream
          • 常用方法详情
          • 代码示例
      • OutputStream
        • FileOutputStream
          • 常用方法详情
          • 代码示例
        • BufferedOutputStream
          • 常用方法详情
          • 代码示例
      • Read
      • Write

Java的java.io库提供了IO接口,IO是以流为基础进行输入输出的。

流又可以分为:输入流、输出流、字节流、字符流等。流相互结合使用,有字节输入流、字节输出流、字符输入流、字符输出流等。

输入流表示从一个源读取数据,输出流表示向一个目标写数据。

字节流操作的数据单元是字节(byte),字符流操作的数据单元是字符(char)。

在这里插入图片描述
输入流的基类:InputStream、Reader 主要用于读数据

输出流的基类:OutputStream、Writer 主要用于写数据

字节流的基类:InputStream、OutputStream

字符流的基类:Reader、Writer

InputStream

主要方法:
在这里插入图片描述
常用方法详情:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
相应接口文档可查看:java文档中文

FileInputStream

FileInputStream 继承了InputStream ,主要方法:
在这里插入图片描述
在这里插入图片描述

常用方法详情

构造方法,常用于连接实际文件创建一个FileInputStream 对象,使用该对象完成上述流的操作
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码示例

从一个文件中读取字节数据,先创建一个data.txt ,输入:北国风光,千里冰封,万里雪飘。望长城内外,惟余莽莽;大河上下,顿失滔滔。
以UTF-8编码保存。

public class InputStreamDemo {

    public static void main(String[] args) {
        // data.txt 路径
        String fileName = "D:\\work\\workspace\\java-learn\\io\\data.txt";
        readMsg(fileName);
    }

    public static void readMsg(String fileName) {
        byte[] data = null;
        try {
            // 创建输入流
            FileInputStream fis = new FileInputStream(fileName);
            // 在读写操作前获取数据流的字节大小
            int readSize = fis.available();
            data = new byte[readSize];
            // 从输入流fis中读取data.length字节数据到字节数组data
            // 这里的读数据,还可以根据fis.read())!=-1,一个个字节读取。
            fis.read(data);
            // 释放资源
            fis.close();

            System.out.println("size = " + readSize);
            // 遍历字节数组
            for (int i = 0; i < data.length; i++) {
                System.out.print(data[i] + "、");
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述
在这里插入图片描述
这样,就完成了使用FileInputStream 读取文件数据。可以使用data.txt 内容直接转换成字节数组,看看与FileInputStream 读取文件数据内容是否一致。

public static void main(String[] args) {
        // data.txt 路径
//        String fileName = "D:\\work\\workspace\\java-learn\\io\\data.txt";
//        readMsg(fileName);

        String s = "北国风光,千里冰封,万里雪飘。望长城内外,惟余莽莽;大河上下,顿失滔滔。";
        try {
            byte[] data = s.getBytes("UTF-8");
            System.out.println("字节数组大小: " + data.length);
            // 遍历字节数组
            for (int i = 0; i < data.length; i++) {
                System.out.print(data[i] + "、");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

    }

在这里插入图片描述
对比一致。这样就可以在已经有文件的时候,使用FileInputStream 读取相应文件内容。
在接口文档中,read有三种读取方式:
1、read()

public static void readMsg2(String fileName) {
        try {
            // 创建输入流
            FileInputStream fis = new FileInputStream(fileName);
            int b;
            while ((b = fis.read()) != -1) {
                // 因为fis.read() 返回值是一个个字节的整形,这里需要转换一下
                System.out.print((byte)b + "、");
            }
            // 释放资源
            fis.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

这个方法要注意的是read()返回值是整形,至于为什么,可以参考:https://blog.csdn.net/music0ant/article/details/60337974

2、read(byte[] bytes)

这个方法就是上面的例子使用的

** 3、read(byte[] b, int off, int len) **

public static void readMsg3(String fileName) {
        byte[] data = null;
        try {
            // 创建输入流
            FileInputStream fis = new FileInputStream(fileName);
            // 这里设置的大小一般为1024的倍数
            data = new byte[1024];
            int len;
            while ((len = fis.read(data, 0, data.length)) != -1) {
            	// 字节转换成字符
                System.out.println(new String(data, 0, len));
            }
            // 释放资源
            fis.close();

            // 遍历字节数组
            for (int i = 0; i < data.length; i++) {
                System.out.print(data[i] + "、");
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

BufferInputStream

BufferedInputStream 是FilterInputStream 的子类,而FilterInputStream 又是InputStream 的子类
FileInputStream 的read() 方法,是直接从磁盘中读取数据至内存;而BufferedInputStream 底层是维护了一块大小为
DEFAULT_BUFFER_SIZE = 8192 的缓存区,它read()方法会使用到fill() 方法,该方法完成将数据存放到缓冲区中,但该方法内,底层会调用FileInputStream 的read() 方法,将数据从磁盘取出。

  1. 使用BufferedInputStream 需要传入一个InputStream
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\work\\workspace\\java-learn\\io\\data.txt"));

这时,BufferedInputStream 获取到了相应的FileputStream 流及设置了默认的缓存区大小

public BufferedInputStream(InputStream in) {
        this(in, DEFAULT_BUFFER_SIZE);
}

in 代表了流

  1. 然后在使用BufferedInputStream 的read()方法时(包括有参及无参的方法),都会存三两个方法的调用:fill()和getInIfOpen()及getBufIfOpen()
public synchronized int read() throws IOException {
        if (pos >= count) {
            fill();
            if (pos >= count)
                return -1;
        }
        return getBufIfOpen()[pos++] & 0xff;
    }
public synchronized int read(byte b[], int off, int len)
        throws IOException
    {
        getBufIfOpen(); 
        .....省略
            int nread = read1(b, off + n, len - n);// 调用read1() 中含有fill() 方法
        .....省略
    }

private int read1(byte[] b, int off, int len) throws IOException {
        .....省略
            if (len >= getBufIfOpen().length && markpos < 0) {
                return getInIfOpen().read(b, off, len);
            }
            fill();
        .....省略
        System.arraycopy(getBufIfOpen(), pos, b, off, cnt);
        pos += cnt;
        return cnt;
    }
private void fill() throws IOException {
        byte[] buffer = getBufIfOpen();
        if (markpos < 0)
            pos = 0;            /* no mark: throw away the buffer */
        else if (pos >= buffer.length)  /* no room left in buffer */
            if (markpos > 0) {  /* can throw away early part of the buffer */
                int sz = pos - markpos;
                System.arraycopy(buffer, markpos, buffer, 0, sz);
                pos = sz;
                markpos = 0;
            } else if (buffer.length >= marklimit) {
                markpos = -1;   /* buffer got too big, invalidate mark */
                pos = 0;        /* drop buffer contents */
            } else if (buffer.length >= MAX_BUFFER_SIZE) {
                throw new OutOfMemoryError("Required array size too large");
            } else {            /* grow buffer */
                int nsz = (pos <= MAX_BUFFER_SIZE - pos) ?
                        pos * 2 : MAX_BUFFER_SIZE;
                if (nsz > marklimit)
                    nsz = marklimit;
                byte nbuf[] = new byte[nsz];
                System.arraycopy(buffer, 0, nbuf, 0, pos);
                if (!bufUpdater.compareAndSet(this, buffer, nbuf)) {
                    // Can't replace buf if there was an async close.
                    // Note: This would need to be changed if fill()
                    // is ever made accessible to multiple threads.
                    // But for now, the only way CAS can fail is via close.
                    // assert buf == null;
                    throw new IOException("Stream closed");
                }
                buffer = nbuf;
            }
        count = pos;
        int n = getInIfOpen().read(buffer, pos, buffer.length - pos);
        if (n > 0)
            count = n + pos;
    }
  1. getInIfOpen() 获取到了in流,getBufIfOpen() 获取到了缓存区,使用read() 方法就获取到了缓存区内的数据。
private InputStream getInIfOpen() throws IOException {
        InputStream input = in;
        if (input == null)
            throw new IOException("Stream closed");
        return input;
    }
private byte[] getBufIfOpen() throws IOException {
        byte[] buffer = buf;
        if (buffer == null)
            throw new IOException("Stream closed");
        return buffer;
    }

BufferedInputStream
当创建BufferedInputStream时,将创建一个内部缓冲区数组。 当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次有多个字节。 mark操作会记住输入流中的一点,并且reset操作会导致从最近的mark操作之后读取的所有字节在从包含的输入流中取出新的字节之前重新读取。
主要方法:
在这里插入图片描述
在这里插入图片描述

常用方法详情

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码示例

1、read()
直接使用read() 方法逐步读取

public static void read(String file) {
        try {
            // 获取文件的输入流
            FileInputStream fis = new FileInputStream(file);
            // 使用构造方法获取缓冲流对象
            BufferedInputStream bis = new BufferedInputStream(fis);
            // 记录数据的下一个字节,如果到达了流的末尾,为 -1
            int len;
            // 计算有多少的字节
            // 判断是否到达流的末尾,退出循环
            while ((len = bis.read()) != -1) {
                // read() 返回的是字节的整形,需要转换
                System.out.print((byte)len + "、");
            }

            // 释放资源
            bis.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

2、通过read(byte[] b)读取

public static void read2(String file) {
        try {
            FileInputStream fis = new FileInputStream(file);
            BufferedInputStream bis = new BufferedInputStream(fis);
            // 设置读取数据的缓冲区,这里设置读取字节最多为b的长度1024
            byte[] b = new byte[1024];
            // 读取到缓冲区的总字节数,或者如果没有更多的数据,因为已经到达流的末尾,则是 -1
            // 也就是上面的缓冲区设置的b长度,就是通过bis.read(b)一步步获取,直到最后的 -1
            int len;
            // 如果new byte[16],则len 会为:16、16、16、16、16、16、14
            // 如果new byte[32],则len 会为:32、32、32、14
            // 如果new byte[64],则len 会为:64、46
            while ((len = bis.read(b)) != -1) {
                // 根据读取到的字节长度为len 的b 数组进行解码打印
                // 注意如果分配的缓冲区长度不够放置完整字符,将会产生乱码,
                // 比如new byte[16],这里将会出现乱码,因为读取的句子有字符被“切割开”了。无法解析相应字节
                System.out.printf(new String(b, 0, len));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

3、通过read(byte[] b,int off,int len)读取

public static void read3(String file) {
        FileInputStream fis = null;
        byte[] data = null;
        try {
            fis = new FileInputStream(file);
            BufferedInputStream bis = new BufferedInputStream(fis);
            data = new byte[1024];
            int len;
            while ((len = bis.read(data, 0, data.length)) != -1) {
                System.out.println(new String(data, 0, len));
            }
            // 释放资源
            fis.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

结果:
在这里插入图片描述

OutputStream

FileOutputStream

文件输出流是用于将数据写入到输出流File或一个FileDescriptor 。
File 都好理解,FileDescriptor 是文件描述符,可以看作是系统为了管理已经打开的文件,而创建的文件索引。一个文件描述符对应一个文件,不同的文件描述符可以对应同一个文件。执行IO操作需要通过文件描述符。

常用方法详情

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
具体使用:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
该方法可以获取到文件描述符
在这里插入图片描述

代码示例

1、write(byte[] b):

public class FileOutputStreamDemo {

    public static void main(String[] args) {
        String fileName = "D:\\work\\workspace\\java-learn\\io\\out.txt";
        String date = "惜秦皇汉武,略输文采。唐宗宋祖,稍逊风骚。一代天骄,成吉思汗。数风流人物,还看今朝。";
        byte[] bytes = date.getBytes();
        // 指定编码
        // byte[] bytes = date.getBytes("UTF-8");
        saveMsg(fileName, bytes);
    }

    public static void saveMsg(String fileName, byte[] data) {
        FileOutputStream foStream = null;
        try {
            foStream = new FileOutputStream(fileName);
            foStream.write(data);
            foStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (foStream != null) {
                try { foStream.close();} catch (Exception ee) {}
            }
        }
    }
}

结果:
在这里插入图片描述
2、write(byte[] b, int off, int len)
根据偏移量写入

public class FileOutputStreamDemo {

    public static void main(String[] args) {
        String fileName = "D:\\work\\workspace\\java-learn\\io\\out.txt";
        String date = "惜秦皇汉武,略输文采。唐宗宋祖,稍逊风骚。一代天骄,成吉思汗。数风流人物,还看今朝。";
        byte[] bytes = date.getBytes();
        // 指定编码
        // byte[] bytes = date.getBytes("UTF-8");
//        saveMsg(fileName, bytes);
        saveMsg2(fileName, bytes);
    }

    public static void saveMsg2(String fileName, byte[] data) {
        FileOutputStream foStream = null;
        try {
            foStream = new FileOutputStream(fileName);
            // 偏移12个字符,从“武”开始写入
            foStream.write(data, 12, 21);
            foStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (foStream != null) {
                try { foStream.close();} catch (Exception ee) {}
            }
        }
    }

    public static void saveMsg(String fileName, byte[] data) {
        FileOutputStream foStream = null;
        try {
            foStream = new FileOutputStream(fileName);
            foStream.write(data);
            foStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (foStream != null) {
                try { foStream.close();} catch (Exception ee) {}
            }
        }
    }
}

结果:
在这里插入图片描述

BufferedOutputStream

和BufferedInputStream 一样,为了提高读写速度,使用BufferedOutputStream ,在写数据到文件时,不会直接写,而是先写到缓冲区,缓冲区满了,在通过flush() 方法刷新缓冲流,从缓冲区写数据到文件。BufferedOutputStream 默认使用8192 大小的缓冲区。在默认构造方法中定义。可以调用含有int size 构造方法设定缓冲区大小。

常用方法详情

在这里插入图片描述

public BufferedOutputStream(OutputStream out) {
        this(out, 8192);
}

public BufferedOutputStream(OutputStream out, int size) {
        super(out);
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码示例
public class BufferedOutputStreamDemo {

    public static void main(String[] args) {
        String fileName = "D:\\work\\workspace\\java-learn\\io\\bufferedOut.txt";
        String date = "Buffered 惜秦皇汉武,略输文采。唐宗宋祖,稍逊风骚。一代天骄,成吉思汗。数风流人物,还看今朝。";
        byte[] bytes = date.getBytes();
//        saveMsg(fileName, bytes);
        saveMsg2(fileName, bytes);
    }

    public static void saveMsg2(String file, byte[] data) {
        BufferedOutputStream bos = null;
        try {
            bos = new BufferedOutputStream(new FileOutputStream(file));
            // 从“秦”开始写,写4个字符
            bos.write(data, 12, 12);
            // 刷新缓冲输出流
            bos.flush();
            bos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try { bos.close();} catch (Exception ee) {}
            }
        }
    }

    public static void saveMsg(String file, byte[] data) {
        BufferedOutputStream bos = null;
        try {
            bos = new BufferedOutputStream(new FileOutputStream(file));
            bos.write(data);
            // 刷新缓冲输出流
            bos.flush();
            bos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try { bos.close();} catch (Exception ee) {}
            }
        }
    }
}

结果:
全写
在这里插入图片描述
根据偏移量写
在这里插入图片描述

Read

Write

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/172244.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

云原生技能树-docker image 操作-练习篇

从Docker Hub 拉取已有镜像 一个Docker 镜像(image)包含了程序代码和程序运行所依赖的所有环境。 Docker 镜像一般存放在镜像仓库服务(Image Registry)里&#xff0c;默认的镜像仓库服务是Docker Hub。 用户可以制作、构建镜像、将镜像上传到镜像仓库服务&#xff0c;从而可以…

100w人在线的 弹幕 系统,是怎么架构的?

Shopee是东南亚及中国台湾地区的电商平台 。2015年于新加坡成立并设立总部&#xff0c;随后拓展至马来西亚、泰国、中国台湾地区、印度尼西亚、越南及菲律宾共七大市场。 Shopee拥有商品种类&#xff0c;包括电子消费品、家居、美容保健、母婴、服饰及健身器材等。 2022年第二…

【STM32学习】GPIO口的八种工作模式

GPIO口的八种工作模式一、参考资料二、施密特触发器1、电路2、电路计算一、参考资料 GPIO原理图详解 强烈建议观看&#xff1a;GPIO为什么这样设计&#xff1f; 施密特触发器—原理 施密特触发器—计算 什么是运放的虚短和虚断&#xff1f; 二、施密特触发器 关于GPIO的原理与…

JavaWeb-JSP

JavaWeb-JSP 1&#xff0c;JSP 概述 JSP&#xff08;全称&#xff1a;Java Server Pages&#xff09;&#xff1a;Java 服务端页面。是一种动态的网页技术&#xff0c;其中既可以定义 HTML、JS、CSS等静态内容&#xff0c;还可以定义 Java代码的动态内容&#xff0c;也就是 J…

设计模式 (二) 工厂模式 Java

目录 一、案例引出 二、简单工厂模式 二、抽象工厂 工厂设计模式&#xff0c;顾名思义类似一家工厂来制造各种产品&#xff0c;目的在于提高代码的可扩展性。 一、案例引出 通过接口来实现一类产品的功能&#xff0c;如目前有飞机、轮船、汽车这类产品的实体类&#xff0c…

Windows 安装 Android Studio

1、下载Android Studio https://r1—sn-2x3edn7s.gvt1.com/edgedl/android/studio/install/2022.1.1.19/android-studio-2022.1.1.19-windows.exe?cms_redirectyes&mhBy&mip175.146.144.124&mm28&mnsn-2x3edn7s&msnvh&mt1673878346&mvm&mvi1…

Pycharm社区版侧边栏没有database按钮

Pycharm有专业版和社区版这两个版本&#xff0c;普通人在大多数情况下我们都会选择社区版进行下载安装。为啥呢&#xff1f;因为社区版免费&#xff0c;专业版收费一般人用不起呀&#xff0c;而且社区版能够基本满足我们的日常需求&#xff08;但是这也就意味着社区版会比专业版…

LINUX学习之查看文件常用命令(四)

cat 命令描述 cat命令是一种用于查看文件内容的命令&#xff0c;它可以将文件的内容直接输出到标准输出 以下是cat命令常用参数&#xff1a; -A &#xff1a;显示所有字符&#xff0c;包括特殊字符-b &#xff1a;显示行号&#xff0c;仅针对非空白行-E &#xff1a;在每行…

【Java集合进阶】Collection 体系集合详解(ArrayList,LinkedList,HashSet,TreeSet...)

文章目录1. 概念2. 集合和数组的区别3. 集合的体系结构4. Collection父接口5. List 子接口6. List 实现类6.1 ArrayList 类6.2 Vector 类6.3 LinkedList 类6.4 ArrayList和LinkedList的区别7. Set 子接口8. Set 实现类8.1 HashSet 类8.2 TreeSet 类9. Collections 工具类Java编…

Vue9-数据代理

数据代理&#xff1a;通过一个对象代理对另一个对象中属性的操作&#xff08;读写&#xff09; 结论&#xff1a;Vue中通过vm&#xff08;实例对象&#xff09;来代理data中的所有数据 1.首先创建了一个vm对象 2.然后 vue就给vm准备了一些数据&#xff0c;当然也将data存放到…

Ubuntu下源码编译VirtualBox二 —— 源码编译(1)

先打个预防针&#xff1a;在Ubuntu下编译VirtualBox可以说相当复杂。 1. 编译指导 &#xff08;1&#xff09;进入技术文档页面 在VirtualBox主页&#xff08;Oracle VM VirtualBox&#xff09;中&#xff0c;鼠标左键点击“Documentation”下的“Technical docs”&#xff0…

【Android安全】安装mitmproxy Https抓包证书 | 安卓SSL抓包

安装mitmproxy Https抓包证书 macbook上 mitmproxy 抓取安卓手机https流量 重点是安装mitmproxy Https抓包证书 前提 手机需要root&#xff0c;macbook上需要安装好mitmproxy macbook安装mitmproxy 需要完成下文1-3&#xff1a; https://github.com/doug-leith/cydia &…

【内排序 -- 八大排序】

目录&#xff1a;前言算法实现&#xff08;一&#xff09;插入排序1.直接插入排序2.希尔排序&#xff08;缩小增量排序&#xff09;&#xff08;二&#xff09;选择排序1.选择排序2.堆排序&#xff08;三&#xff09;交换排序冒泡排序快速排序1&#xff08;hoare版&#xff09;…

ARM S5PV210的SD卡启动实战

一、S5PV210的SD卡启动实战1 1、任务&#xff1a;大于16KB的bin文件使用 SD 卡启动 (1) 总体思路&#xff1a;将我们的代码分为 2 部分&#xff1a;第一部分 BL1 ≤ 16KB&#xff0c;第二部分为任意大小。 iROM 代码执行完成后&#xff0c;从 SD 卡启动会自动读取 BL1 到 SRA…

多核缓存一致性问题及解决方案MESI协议《深入浅出计算机组成原理》学习笔记 Day 4

系列文章目录 这是本周期内系列打卡文章的所有文章的目录 《Go 并发数据结构和算法实践》学习笔记 Day 1《Go 并发数据结构和算法实践》学习笔记 Day 2《说透芯片》学习笔记 Day 3 文章目录系列文章目录前言一、多核缓存一致性从何而来&#xff08;What&#xff09;二、怎么解…

学习TinyRenderer

1图形学图形学&#xff0c;简单来讲是将3D数据以各个视觉效果呈现在2D画布&#xff08;屏幕&#xff09;上&#xff1b;2 TinyRendererTinyRenderer从零开始实现了一个渲染器&#xff1b;TinyRenderer代码地址&#xff1a;https://github.com/ssloy/tinyrenderer内容介绍在&…

ThreeDXF预览DXF文件集成到vue项目中

由于网上资料都是html的&#xff0c;而自己需要嵌入到vue项目中&#xff0c;查找资料都是在index.html引入script脚本&#xff0c;在写到Vue文件中&#xff0c;但是我尝试过了&#xff0c;各种报错&#xff0c;找不到&#xff0c;window. 根本无法用&#xff0c;于是改注入main…

主动服务再升级!这个品牌引领智慧生活进入“深度体验”

文|智能相对论作者| 佘凯文1月15日&#xff0c;一档央视新闻的新概念科技节目《KU A &#xff01;酷啊未来 | 中国科技创新之夜》正式播出&#xff0c;来自中国科学院的多领域顶级科学家及许多科技企业、青年科研人员代表&#xff0c;共同分享了科技创新之路上的成果和突破。不…

EDI文件处理失败如何汇总?

知行之桥EDI系统在后台自动运行的时候&#xff0c;有时会遇到处理文件失败的情况&#xff0c;导致失败的原因有很多&#xff0c;部分客户希望把处理失败的文件都汇总起来&#xff0c;便于分析失败原因&#xff0c;减少未来再出现类似的错误&#xff0c;同时也能够方便后期排查&…

ERD Online 4.0.7 在线数据库建模、元数据管理(免费、私有部署)

4.0.7❝ feat(erd): 增加新春火红主题feat(erd): 增加团队协作人员进入、退出提示fix(erd): 修复权限配置页面显示混乱doc(erd): 修改更新通告地址❞变化一览 增加新春火红主题 新春主题所有按钮、菜单、元素由原来的蓝色改为火红色修复权限配置页面显示混乱 团队功能增加团队协…