Fluxo Java IO (1) Noções básicas de IO

Visão geral

A essência do fluxo IO
  • E/S significa Entrada/Saída, ou seja, entrada/saída durante a transmissão de dados, e entrada e saída são relativas à memória.
  • Fluxos Java IO (entrada/saída) são o principal componente usado por Java para lidar com leitura e gravação de dados
  • Mídias de E/S comuns incluem
    • Arquivo ( entrada | saída )
    • rede ( entrada | saída )
    • Teclado ( saída )
    • Exibição ( saída )
  • cenas a serem usadas
    • Cópia de arquivo (Arquivo)
    • Upload e download de arquivos
    • Importação e exportação de Excel
    • Transmissão de dados em programas de rede (ferramentas de chat)

Classificação

Visão geral

Quase todas as operações IO em Java requerem o uso do pacote java.io; os fluxos podem ser classificados da seguinte forma

  • Dividido pela direção do fluxo (os processos de entrada e saída são geralmente considerados da perspectiva do programa)
    • Fluxo de entrada (entrada)
    • Saída
  • De acordo com o tipo de processamento de fluxo
    • Fluxo de bytes (byte): Byte é a unidade básica da capacidade de armazenamento do computador (Byte), 1B = 8b, ocupa 8 bits em binário
    • Fluxo de caracteres (char): Caractere é o nome coletivo para texto ou símbolos

        Nota: O fluxo de bytes pode ler qualquer tipo de arquivo, como arquivos do tipo binário (fotos, vídeos, áudios, arquivos compactados, etc.), enquanto o fluxo de caracteres é usado para ler arquivos do tipo texto.

  • De acordo com a função do fluxo
    • Fluxo do nó (interagir diretamente com fontes de entrada e saída)
    • Processando streams (streams que agrupam outros streams: encapsulando streams)

Fluxo de bytes (InputStream && OutputStream)

Diagrama de classes InputStream
Diagrama de classes OutputStream

Fluxos de bytes comumente usados ​​em processos de desenvolvimento diários:

FileInputStream && FileOutputStream: comumente usado para implementar cópia/cópia de arquivo
BufferedInputStream && BufferedOutputStream: Para reduzir o número de vezes de IO e melhorar a eficiência de leitura
PrintStream: derivado de OutputStream, fluxo de saída de impressão de bytes padrão (princípio de implementação da estrutura de log)
ZipOutputStream && ZipInputStream: usado para compactação/descompactação de arquivos

Fluxo de caracteres (leitor e escritor)

Diagrama de classes do leitor
Diagrama de classes do escritor

Fluxos de caracteres comumente usados ​​em processos diários de desenvolvimento:

FileReader&&FileWriter: usa FileInputStream && FileOutputStream
BufferedReader&&BufferedWriter: A função é a mesma que BufferedInputStream && BufferedOutputStream, ao mesmo tempo, BufferedReader fornece um método de leitura de texto linha por linha para facilitar o processamento de texto.
Extensão: sabemos que os fluxos de bytes podem ler qualquer arquivo, por que precisamos projetar um fluxo de caracteres?
  • Para arquivos de caracteres, primeiro transfira-os como bytes -> depois converta-os em caracteres, o que consome mais tempo.
  • Para arquivos de caracteres, se o texto for chinês, ele será facilmente distorcido.

Padrões de design

Uma variedade de padrões de design são usados ​​em fluxos de E/S, incluindo os seguintes:

modo adaptador

O padrão Adapter permite que classes trabalhem juntas que de outra forma não funcionariam juntas devido a interfaces incompatíveis .

Para realizar a conversão mútua entre fluxo de caracteres e fluxo de bytes em Java IO, duas classes de adaptadores são projetadas.

InputStreamReader e OutputStreamWriter

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

Padrão de decorador

O padrão decorador pode anexar dinamicamente novas funcionalidades a objetos existentes sem alterar a funcionalidade dos objetos existentes. FilterInputStream, uma subclasse de InputStream, FilterOutputStream, uma subclasse de OutputStream, BufferedReader e FilterReader, subclasses de Reader, e BufferedWriter, FilterWriter e PrintWriter, subclasses de Writer, são todas classes decorativas abstratas. Funcionalidade aprimorada de objetos de subclasse.

prática

ZipOutputStream&&FileOutputStream&&FileInputStream implementa compactação de arquivo

/**
 * 功能: 通过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;
}

Acho que você gosta

Origin blog.csdn.net/qq_34020761/article/details/132337756
Recomendado
Clasificación