001/* 002 * Copyright (c) 2023-2026, Agents-Flex (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.agentsflex.core.file2text.extractor.impl; 017 018 019import com.agentsflex.core.file2text.extractor.FileExtractor; 020import com.agentsflex.core.file2text.source.DocumentSource; 021import com.agentsflex.core.file2text.util.EncodingDetectUtil; 022 023import java.io.InputStream; 024import java.util.Collections; 025import java.util.HashSet; 026import java.util.Set; 027 028/** 029 * 纯文本文件提取器(支持 UTF-8、GBK、GB2312 编码自动检测) 030 * 支持 .txt, .md, .log, .csv, .json, .xml 等文本格式 031 */ 032public class PlainTextExtractor implements FileExtractor { 033 034 private static final Set<String> SUPPORTED_MIME_TYPES; 035 private static final Set<String> SUPPORTED_EXTENSIONS; 036 037 static { 038 Set<String> mimeTypes = new HashSet<>(); 039 mimeTypes.add("text/plain"); 040 mimeTypes.add("text/markdown"); 041 mimeTypes.add("text/csv"); 042 mimeTypes.add("application/json"); 043 mimeTypes.add("application/xml"); 044 SUPPORTED_MIME_TYPES = Collections.unmodifiableSet(mimeTypes); 045 046 Set<String> extensions = new HashSet<>(); 047 extensions.add("txt"); 048 extensions.add("text"); 049 extensions.add("md"); 050 extensions.add("markdown"); 051 extensions.add("log"); 052 extensions.add("csv"); 053 extensions.add("json"); 054 extensions.add("xml"); 055 extensions.add("yml"); 056 extensions.add("yaml"); 057 extensions.add("properties"); 058 extensions.add("conf"); 059 SUPPORTED_EXTENSIONS = Collections.unmodifiableSet(extensions); 060 } 061 062 @Override 063 public boolean supports(DocumentSource source) { 064 String mimeType = source.getMimeType(); 065 String fileName = source.getFileName(); 066 067 if (mimeType != null && (mimeType.startsWith("text/") || SUPPORTED_MIME_TYPES.contains(mimeType))) { 068 return true; 069 } 070 071 if (fileName != null) { 072 String ext = getExtension(fileName); 073 return ext != null && SUPPORTED_EXTENSIONS.contains(ext.toLowerCase()); 074 } 075 076 return false; 077 } 078 079 @Override 080 public String extractText(DocumentSource source) { 081 try (InputStream is = source.openStream()) { 082 return EncodingDetectUtil.readToString(is); 083 } catch (Exception e) { 084 throw new RuntimeException(e); 085 } 086 } 087 088 089 @Override 090 public int getOrder() { 091 return 5; // 高优先级 092 } 093 094 private String getExtension(String fileName) { 095 if (fileName == null || !fileName.contains(".")) return null; 096 int lastDot = fileName.lastIndexOf('.'); 097 return fileName.substring(lastDot + 1).toLowerCase(); 098 } 099}