shikeying
2024-01-11 3b67e947e36133e2a40eb2737b15ea375e157ea0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package com.walker.file;
 
import com.walker.infrastructure.utils.FileUtils;
import com.walker.infrastructure.utils.LongCalendar;
import com.walker.infrastructure.utils.NumberGenerator;
import com.walker.infrastructure.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.io.IOException;
import java.io.InputStream;
 
public abstract class AbstractFileOperateEngine implements FileOperateEngine{
 
    protected final transient Logger logger = LoggerFactory.getLogger(getClass());
 
    @Override
    public void close() {
 
    }
 
    @Override
    public byte[] downloadFile(String id) throws FileOperateException{
        if(StringUtils.isEmpty(id)){
            throw new IllegalArgumentException("文件id不能为空!");
        }
        FileInfo fileInfo = this.getFileInfo(id);
        if(fileInfo == null){
            throw new FileOperateException("文件不存在, fileId=" + id, null);
        }
        return this.executeDownload(fileInfo);
    }
 
    @Deprecated
    @Override
    public FileInfo uploadFile(InputStream inputStream, String fileName, String groupId, long fileSize) throws FileOperateException{
        return this.uploadFile(inputStream, fileName, groupId, fileSize, null, "-1");
    }
 
    @Override
    public FileInfo[] uploadFile(InputStream[] inputStream
            , String[] fileName, String groupId, long[] fileSize, Integer businessType, String owner) throws FileOperateException{
        if(inputStream == null || fileName == null || fileSize == null){
            throw new IllegalArgumentException("上传多个文件,参数为空");
        }
        if(inputStream.length != fileName.length || inputStream.length != fileSize.length){
            throw new IllegalArgumentException("上传多个文件,inputStream, fileName, fileSize个数必须一致!");
        }
 
        int size = inputStream.length;
        FileInfo[] fileInfos = new FileInfo[size];
        for(int i=0; i<size; i++){
            fileInfos[i] = this.uploadFile(inputStream[i], fileName[i], groupId, fileSize[i], businessType, owner);
        }
        return fileInfos;
    }
 
    @Override
    public FileInfo uploadFile(InputStream inputStream
            , String fileName, String groupId, long fileSize, Integer businessType, String owner) throws FileOperateException {
        AbstractFileInfo fileInfo = (AbstractFileInfo) this.acquireFileInfo(fileName);
        if(fileInfo == null){
            throw new IllegalArgumentException("acquireFileInfo()为空,请先实现该方法!");
        }
        // 2023-10-13 生成id使用数值,原来使用字符串(强制转换的),现在id支持集群使用字符串。
//        fileInfo.setId(NumberGenerator.getLongSequenceId());
        fileInfo.setId(String.valueOf(NumberGenerator.getLongSequenceNumber()));
        fileInfo.setFileName(fileName);
        fileInfo.setFileExt(FileUtils.getFileExt(fileName));
        fileInfo.setFileStoreType(this.getFileStoreType());
        fileInfo.setGroupId(groupId);
        fileInfo.setFileSize(fileSize);
        if(businessType != null){
            fileInfo.setBusinessType(businessType);
        } else {
            fileInfo.setBusinessType(-1);
        }
        fileInfo.setOwner(owner);
        try{
            this.executeUpload(inputStream, fileInfo);
        } catch (Exception ex){
            throw new FileOperateException("上传文件错误:" + ex.getMessage(), ex);
        } finally {
            if(inputStream != null){
                try {
                    inputStream.close();
                } catch (IOException e) {}
            }
        }
 
        try {
            this.writeFileInfo(fileInfo);
        } catch (Exception ex){
            throw new FileOperateException("保存上传文件信息错误:" + ex.getMessage(), ex);
        }
        return fileInfo;
    }
 
    @Override
    public FileInfo uploadFile(String filePath, String groupId) throws FileOperateException {
        throw new UnsupportedOperationException("代码未实现");
    }
 
    /**
     * 返回要保存文件的目录,系统生成,如: /fileRoot/2023/02/
     * <pre>
     *     1.对于ftp,url为全路径,因为根路径已在服务中固定,如: /fileRoot/2023/02/
     *     2.对于磁盘,url为相对路径,根路径依据配置动态拼接,如: 2023/02/
     * </pre>
     * @param containRoot 是否包含根路径
     * @return
     */
    protected String generateSaveFolder(boolean containRoot){
        if(StringUtils.isEmpty(this.fileRoot)){
            throw new IllegalArgumentException("请设置根目录:fileRoot");
        }
 
        StringBuilder filePath = new StringBuilder();
        if(containRoot){
            filePath.append(this.fileRoot);
            if(!this.fileRoot.endsWith("/")){
                filePath.append("/");
            }
            filePath.append(LongCalendar.getCurrentMonth());
            return filePath.toString();
        } else {
            // 本地文件存储,不存根路径,只要相对路径
            return LongCalendar.getCurrentMonth();
        }
    }
 
    /**
     * 返回文件名,不带路径,如: demo.txt
     * @param fileInfo
     * @return
     */
    protected String getFileName(FileInfo fileInfo){
        return new StringBuilder(fileInfo.getId())
                .append(StringUtils.EXTENSION_SEPARATOR).append(fileInfo.getFileExt()).toString();
    }
 
    public String getFileRoot() {
        return fileRoot;
    }
 
    @Override
    public void setFileRoot(String fileRoot) {
        this.fileRoot = fileRoot;
    }
 
    private String fileRoot = null;
 
    /**
     * 获得上传文件结果对象。
     * @param fileName 文件名,如: demo.txt
     * @return
     */
    protected abstract FileInfo acquireFileInfo(String fileName);
 
    /**
     * 执行上传文件动作,由子类实现。
     * @param inputStream
     */
    protected abstract void executeUpload(InputStream inputStream, FileInfo fileInfo) throws FileOperateException;
 
    /**
     * 把上传成功的文件信息写入到持久层(一般为数据库)中。
     * @param fileInfo
     * @throws FileOperateException
     */
    protected abstract void writeFileInfo(FileInfo fileInfo);
 
    /**
     * 执行文件下载操作,并返回文件二进制数据。
     * @param fileInfo
     * @return
     * @throws FileOperateException
     * @date 2023-02-14
     */
    protected abstract byte[] executeDownload(FileInfo fileInfo) throws FileOperateException;
}