Java IO stream (1) IO basics

Overview

The essence of IO stream
  • I/O means Input/Output, that is, input/output during data transmission, and input and output are relative to memory.
  • Java IO (input/output) streams are the key component used by Java to handle reading and writing data
  • Common I|O media include
    • File( input|output )
    • network( input|output )
    • Keyboard ( output )
    • Display ( output )
  • scenes to be used
    • File copy (File)
    • File upload and download
    • Excel import and export
    • Data transmission in network programs (chat tools)

Classification

Overview

Almost all IO operations in Java require the use of the java.io package; streams can be classified as follows

  • Divided by flow direction (input and output processes are usually considered from a program perspective)
    • Input stream (Input)
    • Output
  • According to the type of stream processing
    • Byte stream (byte): Byte is the basic unit of computer storage capacity (Byte), 1B=8b, occupies 8 bits in binary
    • Character stream (char): Character is the collective name for text or symbols

        Note: The byte stream can read any type of file, such as binary type files (pictures, videos, audios, compressed files, etc.), while the character stream is used to read text type files.

  • According to the function of flow
    • Node flow (interact directly with input and output sources)
    • Processing streams (streams that wrap other streams: wrapping streams)

Byte stream (InputStream && OutputStream)

InputStream class diagram
OutputStream class diagram

Byte streams commonly used in daily development processes:

FileInputStream && FileOutputStream: commonly used to implement file copy/copy
BufferedInputStream && BufferedOutputStream: In order to reduce the number of IO times and improve reading efficiency
PrintStream: derived from OutputStream, standard byte print output stream (implementation principle of log framework)
ZipOutputStream && ZipInputStream: used for file compression/file decompression

Character stream (Reader && Writer)

Reader class diagram
Writer class diagram

Character flows commonly used in daily development processes:

FileReader&&FileWriter:作用同FileInputStream && FileOutputStream
BufferedReader&&BufferedWriter: The function is the same as BufferedInputStream && BufferedOutputStream. At the same time, BufferedReader provides a method of reading text line by line to facilitate text processing.
Extension: We know that byte streams can read any file, why do we need to design a character stream?
  • For character files, first transfer them as bytes -> then convert them into characters, which is more time-consuming.
  • For character files, if the text is Chinese, it will be easily garbled.

Design Patterns

A variety of design patterns are used in IO flows, including the following:

adapter mode

The Adapter pattern enables classes to work together that would otherwise not work together due to incompatible interfaces .

In order to realize the mutual conversion between character stream and byte stream in Java IO, two adapter classes are designed.

InputStreamReader和OutputStreamWriter

InputStreamReader isr = new InputStreamReader(new FileInputStream(fileName), "UTF-8");
BufferedReader bufferedReader = new BufferedReader(isr);

Decorator pattern

The decorator pattern can dynamically attach new functionality to existing objects without changing the functionality of the existing objects. FilterInputStream, a subclass of InputStream, FilterOutputStream, a subclass of OutputStream, BufferedReader and FilterReader, subclasses of Reader, and BufferedWriter, FilterWriter and PrintWriter, subclasses of Writer, are all abstract decorative classes. Enhanced functionality of subclass objects.

practice

ZipOutputStream&&FileOutputStream&&FileInputStream implements file compression

/**
 * 功能: 通过ZipOutputStream压缩文件,最后返回压缩包
 * @param files
 * @param fileName
 * @return
 */
public File zipFiles(File[] files,String fileName) {
    File zipFile = null;
    FileOutputStream fosZipFile = null;
    ZipOutputStream zosZipFile = null; //压缩文件输出流
    try {
        zipFile = downloadAttachmentService.createFile("", fileName); //创建一个空的文件目录
        fosZipFile = new FileOutputStream(zipFile); //以文件流从内存中输出
        zosZipFile = new ZipOutputStream(fosZipFile); //以压缩流从内存中输出

        for (File file : files) {
            FileInputStream fis = new FileInputStream(file); //对每个文件创建输入流,读取文件到内存
            ZipEntry zipEntry = new ZipEntry(file.getName()); //ZipEntry用来创建压缩文件
            zosZipFile.putNextEntry(zipEntry); //加入需要压缩的文件

            byte[] bytes = new byte[1024];
            int length;
            while((length = fis.read(bytes)) >= 0) { //读取文件到内存
                zosZipFile.write(bytes, 0, length); //文件写入压缩流
            }
            fis.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally { //关闭流
        try {
            zosZipFile.close();
            fosZipFile.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return zipFile; //返回压缩包
}
/**
 * @Title: createFile
 * @Description: 创建下载目录文件
 * @author Bierce
 * @param rootPath
 * @param filename
 * @return
 * @throws IOException
 */
public File createFile(String rootPath, String filename) throws IOException {
    // Default root path
    if (rootPath.isEmpty()) {
        rootPath = "download-cache";
    }
    File fRoot = new File(rootPath);
    if (!fRoot.exists() || !fRoot.isDirectory()) {
        fRoot.mkdirs();
    }
    // job sub path
    String uuid = UUID.randomUUID().toString();
    String directoryJob = rootPath + File.separator + getClass().getSimpleName() + File.separator + uuid;//文件名称随机生成保证唯一
    File dirJob = new File(directoryJob);
    if (!dirJob.exists() || !dirJob.isDirectory()) {
        dirJob.mkdirs();
    }
    String filePath = directoryJob + File.separator + filename;
    File file = new File(filePath);
    if (!file.exists()) {
        file.createNewFile();
    }
    return file;
}
//-----------------扩展方法-文件名去重保证唯一-----------------
/**
 * @Title: snFileName_noUIID
 * @Description: 去除sn文件UUID以及解决sn文件名重复问题
 * @author Bierce
 * @return file
 */
public File snFileName_noUIID(String fileParentPath,String snFileName,File file){
    //snFileName:完整文件名 sn-xx..UUID..xx.xlsx
    //snFileName_delUIID: sn.xlsx
    //snFileName_prefix: sn
    //suffix:xlsx
    //文件名:如sn.xlsx
    String snFileName_delUIID = snFileName.substring(0,snFileName.length() - 42) + ".xlsx";//42是固定长度:UUID+.xlsx
    String snFileName_prefix = snFileName.substring(0,snFileName.length() - 42);//文件前缀
    String suffix = snFileName.substring(snFileName.lastIndexOf("."));//文件后缀:.xlsx

    try {
        file = new File(fileParentPath + snFileName_delUIID);//设置sn文件所在目录为计划交接文件目录下
        int i = 1;
        //对于同名SN文件情况重新命名
        while(file.exists()) {//保证文件夹下不存在同名文件
            String newFileName = snFileName_prefix + "(" + i + ")" + suffix;
            String parentPath = file.getParent();
            file = new File(parentPath + File.separator + newFileName);
            i++;
        }
        file.createNewFile();//new File 只是创建了一个File对象,还需要调用createNewFile()方法才能实现文件的成功创建
    } catch (Exception e) {
    }
    return file;
}

Guess you like

Origin blog.csdn.net/qq_34020761/article/details/132337756