lucene7.1.0实现搜索文件内容

Lucene的使用主要体现在两个步骤:

  1 创建索引,通过IndexWriter对不同的文件进行索引的创建,并将其保存在索引相关文件存储的位置中。

  2 通过索引查寻关键字相关文档。

首先,我们需要定义一个词法分析器。

Analyzer analyzer = new IKAnalyzer(true);

注意各种词法分析器的区别,详见  http://blog.csdn.net/silentmuh/article/details/78451786

比如一句话,“我爱我们的中国!”,如何对他拆分,扣掉停顿词“的”,提取关键字“我”“我们”“中国”等等。这就要借助的词法分析器Analyzer来实现。这里面使用的是标准的词法分析器,如果专门针对汉语,还可以搭配paoding,进行使用。

第二步,确定索引文件存储的位置,Lucene提供给我们两种方式:

Directory directory = FSDirectory.open(FileSystems.getDefault().getPath(INDEX_DIR));

  1 本地文件存储 

第三步,创建IndexWriter,进行索引文件的写入。

IndexWriterConfig config = new IndexWriterConfig(analyzer);
IndexWriter indexWriter = new IndexWriter(directory, config);

第四步,内容提取,进行索引的存储。

Document doc = new Document();
String text = "This is the text to be indexed.";
doc.add(new Field("fieldname", text, TextField.TYPE_STORED));
iwriter.addDocument(doc);
iwriter.close();

  第一行,申请了一个document对象,这个类似于数据库中的表中的一行。

  第二行,是我们即将索引的字符串。

  第三行,把字符串存储起来(因为设置了TextField.TYPE_STORED,如果不想存储,可以使用其他参数,详情参考官方文档),并存储“表明”为"fieldname".

  第四行,把doc对象加入到索引创建中。

  第五行,关闭IndexWriter,提交创建内容。

这就是索引创建的过程。

 

通过索引查寻关键字相关文档

 第一步,打开存储位置

DirectoryReader ireader = DirectoryReader.open(directory);

  第二步,创建搜索器

IndexSearcher isearcher = new IndexSearcher(ireader);

  第三步,类似SQL,进行关键字查询

复制代码
复制代码
QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, "fieldname", analyzer);
Query query = parser.parse("text");
ScoreDoc[] hits = isearcher.search(query, null, 1000).scoreDocs;
assertEquals(1, hits.length);
for (int i = 0; i < hits.length; i++) {
    Document hitDoc = isearcher.doc(hits[i].doc);
    assertEquals("This is the text to be indexed.",hitDoc.get("fieldname"));
}
复制代码
复制代码

  这里,我们创建了一个查询器,并设置其词法分析器,以及查询的“表名“为”fieldname“。查询结果会返回一个集合,类似SQL的ResultSet,我们可以提取其中存储的内容。

  关于各种不同的查询方式,可以参考官方手册,或者推荐的PPT

  第四步,关闭查询器等。

ireader.close();
directory.close();

 最后,自己写了个简单的例子,可以对一个文件夹内的内容进行索引的创建,并根据关键字筛选文件,并读取其中的内容

复制代码
  1 package muh.test;
  2 
  3 import java.io.BufferedReader;
  4 import java.io.File;
  5 import java.io.FileInputStream;
  6 import java.io.FileNotFoundException;
  7 import java.io.FileReader;
  8 import java.io.FilenameFilter;
  9 import java.io.IOException;
 10 import java.io.InputStreamReader;
 11 import java.nio.file.FileSystems;
 12 import java.util.ArrayList;
 13 import java.util.Date;
 14 import java.util.List;
 15 
 16 import org.apache.lucene.analysis.Analyzer;
 17 import org.apache.lucene.analysis.core.SimpleAnalyzer;
 18 import org.apache.lucene.analysis.standard.StandardAnalyzer;
 19 import org.apache.lucene.document.Document;
 20 import org.apache.lucene.document.Field;
 21 import org.apache.lucene.document.TextField;
 22 import org.apache.lucene.index.DirectoryReader;
 23 import org.apache.lucene.index.IndexReader;
 24 import org.apache.lucene.index.IndexWriter;
 25 import org.apache.lucene.index.IndexWriterConfig;
 26 import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
 27 import org.apache.lucene.queryparser.classic.ParseException;
 28 import org.apache.lucene.queryparser.classic.QueryParser;
 29 import org.apache.lucene.search.BooleanClause;
 30 import org.apache.lucene.search.IndexSearcher;
 31 import org.apache.lucene.search.Query;
 32 import org.apache.lucene.search.ScoreDoc;
 33 import org.apache.lucene.search.TopDocs;
 34 import org.apache.lucene.search.TopScoreDocCollector;
 35 import org.apache.lucene.search.highlight.Highlighter;
 36 import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
 37 import org.apache.lucene.search.highlight.QueryScorer;
 38 import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
 39 import org.apache.lucene.search.highlight.SimpleSpanFragmenter;
 40 import org.apache.lucene.store.Directory;
 41 import org.apache.lucene.store.FSDirectory;
 42 import org.apache.lucene.util.Version;
 43 import org.apache.poi.hssf.usermodel.HSSFCell;
 44 import org.apache.poi.hssf.usermodel.HSSFRow;
 45 import org.apache.poi.hssf.usermodel.HSSFSheet;
 46 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 47 import org.apache.poi.hwpf.HWPFDocument;
 48 import org.apache.poi.hwpf.usermodel.Range;
 49 import org.apache.poi.xssf.usermodel.XSSFCell;
 50 import org.apache.poi.xssf.usermodel.XSSFRow;
 51 import org.apache.poi.xssf.usermodel.XSSFSheet;
 52 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 53 import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
 54 import org.apache.poi.xwpf.usermodel.XWPFDocument;
 55 import org.pdfbox.pdfparser.PDFParser;
 56 import org.pdfbox.pdmodel.PDDocument;
 57 import org.pdfbox.util.PDFTextStripper;
 58 import org.wltea.analyzer.lucene.IKAnalyzer;
 59 
 60 public class LuceneTest {
 61 
 62     private static String INDEX_DIR = "E:\\luceneIndex";
 63     private static String Source_DIR = "E:\\luceneSource";
 64 
 65     /**
 66      * 列出某个路径下的所有文件,包括子文件夹,如果本身就是文件,那么返回自身,需要遍历的文件路径,文件名过滤器
 67      * @Title: listAllFiles 
 68      * @author hegg
 69      * @date 2017年11月6日 下午8:28:54
 70      * @param filePath
 71      * @param fileNameFilter
 72      * @return 返回类型 List<File>
 73      */
 74     public static List<File> listAllFiles(String filePath, FilenameFilter fileNameFilter) {
 75         List<File> files = new ArrayList<File>();
 76         try {
 77             File root = new File(filePath);
 78             if (!root.exists())
 79                 return files;
 80             if (root.isFile())
 81                 files.add(root);
 82             else {
 83                 for (File file : root.listFiles(fileNameFilter)) {
 84                     if (file.isFile())
 85                         files.add(file);
 86                     else if (file.isDirectory()) {
 87                         files.addAll(listAllFiles(file.getAbsolutePath(), fileNameFilter));
 88                     }
 89                 }
 90             }
 91         } catch (Exception e) {
 92             e.printStackTrace();
 93         }
 94         return files;
 95     }
 96 
 97     /**
 98      * 删除文件目录下的所有文件
 99      * @Title: deleteDir 
100      * @author hegg
101      * @date 2017年11月6日 下午8:29:16
102      * @param file
103      * @return 返回类型 boolean
104      */
105     public static boolean deleteDir(File file) {
106         if (file.isDirectory()) {
107             File[] files = file.listFiles();
108             for (int i = 0; i < files.length; i++) {
109                 deleteDir(files[i]);
110             }
111         }
112         file.delete();
113         return true;
114     }
115 
116     /**
117      * 读取txt文件的内容
118      * @Title: readTxt 
119      * @author hegg
120      * @date 2017年11月6日 下午8:15:49
121      * @param file
122      * @return 返回类型 String
123      */
124     public static String readTxt(File file) {
125         String result = "";
126         try {
127             BufferedReader br = new BufferedReader(new FileReader(file));// 构造一个BufferedReader类来读取文件
128             String s = null;
129             while ((s = br.readLine()) != null) {// 使用readLine方法,一次读一行
130                 result = result + "\n" + s;
131             }
132             br.close();
133         } catch (Exception e) {
134             e.printStackTrace();
135         }
136         return result;
137     }
138 
139     /**
140      * 读取Word内容,包括03格式和07格式
141      * @Title: readWord 
142      * @author hegg
143      * @date 2017年11月6日 下午8:15:14
144      * @param file
145      * @param type
146      * @return 返回类型 String
147      */
148     public static String readWord(File file, String type) {
149         String result = "";
150         try {
151             FileInputStream fis = new FileInputStream(file);
152             if ("doc".equals(type)) {
153                 HWPFDocument doc = new HWPFDocument(fis);
154                 Range rang = doc.getRange();
155                 result += rang.text();
156             }
157             if ("docx".equals(type)) {
158                 XWPFDocument doc = new XWPFDocument(fis);
159                 XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
160                 result = extractor.getText();
161             }
162 
163             fis.close();
164         } catch (Exception e) {
165             e.printStackTrace();
166         }
167         return result;
168     }
169 
170     /**
171      * 读取Excel文件内容,包括03格式和07格式
172      * @Title: readExcel 
173      * @author hegg
174      * @date 2017年11月6日 下午8:14:04
175      * @param file
176      * @param type
177      * @return 返回类型 String
178      */
179     public static String readExcel(File file, String type) {
180         String result = "";
181         try {
182             FileInputStream fis = new FileInputStream(file);
183             StringBuilder sb = new StringBuilder();
184             if ("xlsx".equals(type)) {
185                 XSSFWorkbook xwb = new XSSFWorkbook(fis);
186                 for (int i = 0; i < xwb.getNumberOfSheets(); i++) {
187                     XSSFSheet sheet = xwb.getSheetAt(i);
188                     for (int j = 0; j < sheet.getPhysicalNumberOfRows(); j++) {
189                         XSSFRow row = sheet.getRow(j);
190                         for (int k = 0; k < row.getPhysicalNumberOfCells(); k++) {
191                             XSSFCell cell = row.getCell(k);
192                             sb.append(cell.getRichStringCellValue());
193                         }
194                     }
195                 }
196             }
197             if ("xls".equals(type)) {
198                 // 得到Excel工作簿对象
199                 HSSFWorkbook hwb = new HSSFWorkbook(fis);
200                 for (int i = 0; i < hwb.getNumberOfSheets(); i++) {
201                     HSSFSheet sheet = hwb.getSheetAt(i);
202                     for (int j = 0; j < sheet.getPhysicalNumberOfRows(); j++) {
203                         HSSFRow row = sheet.getRow(j);
204                         for (int k = 0; k < row.getPhysicalNumberOfCells(); k++) {
205                             HSSFCell cell = row.getCell(k);
206                             sb.append(cell.getRichStringCellValue());
207                         }
208                     }
209                 }
210             }
211 
212             fis.close();
213             result += sb.toString();
214         } catch (Exception e) {
215             e.printStackTrace();
216         }
217         return result;
218     }
219 
220     /**
221      * 读取pdf文件内容
222      * @Title: readPDF 
223      * @author hegg
224      * @date 2017年11月6日 下午8:13:41
225      * @param file
226      * @return 返回类型 String
227      */
228     public static String readPDF(File file) {
229         String result = null;
230         FileInputStream is = null;
231         PDDocument document = null;
232         try {
233             is = new FileInputStream(file);
234             PDFParser parser = new PDFParser(is);
235             parser.parse();
236             document = parser.getPDDocument();
237             PDFTextStripper stripper = new PDFTextStripper();
238             result = stripper.getText(document);
239         } catch (FileNotFoundException e) {
240             e.printStackTrace();
241         } catch (IOException e) {
242             e.printStackTrace();
243         } finally {
244             if (is != null) {
245                 try {
246                     is.close();
247                 } catch (IOException e) {
248                     e.printStackTrace();
249                 }
250             }
251             if (document != null) {
252                 try {
253                     document.close();
254                 } catch (IOException e) {
255                     e.printStackTrace();
256                 }
257             }
258         }
259         return result;
260     }
261     
262     /**
263      * 读取html文件内容
264      * @Title: readHtml 
265      * @author hegg
266      * @date 2017年11月6日 下午8:13:08
267      * @param file
268      * @return 返回类型 String
269      */
270     public static String readHtml(File file) {
271         StringBuffer content = new StringBuffer("");
272         FileInputStream fis = null;
273         try {
274             fis = new FileInputStream(file);
275             // 读取页面
276             BufferedReader reader = new BufferedReader(new InputStreamReader(fis,"utf-8"));//这里的字符编码要注意,要对上html头文件的一致,否则会出乱码
277             String line = null;
278             while ((line = reader.readLine()) != null) {
279                 content.append(line + "\n");
280             }
281             reader.close();
282         } catch (Exception e) {
283             e.printStackTrace();
284         }
285         String contentString = content.toString();
286         return contentString;
287     }
288 
289     /**
290      * 创建索引
291      * @Title: creatIndex 
292      * @author hegg
293      * @date 2017年11月6日 下午8:29:37 返回类型 void
294      */
295     public static void creatIndex() {
296         Date begin = new Date();
297         // 1、创建Analyzer词法分析器,注意SimpleAnalyzer和StandardAnalyzer的区别
298         Analyzer analyzer  = null;
299         // 2、创建directory,保存索引,可以保存在内存中也可以保存在硬盘上
300         Directory directory = null;
301         // 3、创建indexWriter创建索引
302         IndexWriter indexWriter = null;
303         try {
304 //            analyzer = new StandardAnalyzer();
305 //            analyzer = new SimpleAnalyzer();
306             analyzer = new IKAnalyzer(true);
307 //            directory = FSDirectory.open(new File(INDEX_DIR));
308             directory = FSDirectory.open(FileSystems.getDefault().getPath(INDEX_DIR));
309             // 4、创建indexwriterConfig,并指定分词器版本
310             IndexWriterConfig config = new IndexWriterConfig(analyzer);
311             // 5、创建IndexWriter,需要使用IndexWriterConfig,
312             indexWriter = new IndexWriter(directory, config);
313             indexWriter.deleteAll();
314             
315             File docDirectory = new File(Source_DIR);
316             for (File file : docDirectory.listFiles()) {
317                 String content = "";
318                 //获取文件后缀
319                 String type = file.getName().substring(file.getName().lastIndexOf(".")+1);
320                 if("txt".equalsIgnoreCase(type)){
321                     content += readTxt(file);
322                 }else if("doc".equalsIgnoreCase(type)){
323                     content += readWord(file,"doc");
324                 }else if("docx".equalsIgnoreCase(type)){
325                     content += readWord(file,"docx");
326                 }else if("xls".equalsIgnoreCase(type)){
327                     content += readExcel(file,"xls");
328                 }else if("xlsx".equalsIgnoreCase(type)){
329                     content += readExcel(file,"xlsx");
330                 }else if("pdf".equalsIgnoreCase(type)){
331                     content += readPDF(file);
332                 }else if("html".equalsIgnoreCase(type)){
333                     content += readHtml(file);
334                 }
335                 // 6、创建document
336                 Document document = new Document();
337                 document.add(new Field("content", content, TextField.TYPE_STORED));
338                 document.add(new Field("fileName", file.getName(), TextField.TYPE_STORED));
339                 document.add(new Field("filePath", file.getAbsolutePath(), TextField.TYPE_STORED));
340                 document.add(new Field("updateTime", file.lastModified() + "", TextField.TYPE_STORED));
341                 indexWriter.addDocument(document);
342             }
343             indexWriter.commit();
344         } catch (Exception e) {
345             e.printStackTrace();
346         } finally {
347             try {
348                 if (analyzer != null) analyzer.close();
349                 if (indexWriter != null) indexWriter.close();
350                 if (directory != null) directory.close();
351             } catch (IOException e) {
352                 e.printStackTrace();
353             }
354         }
355 
356         Date end = new Date();
357         System.out.println("创建索引-----耗时:" + (end.getTime() - begin.getTime()) + "ms\n");
358     }
359 
360     /**
361      * 查找索引,返回符合条件的文件
362      * @Title: searchIndex 
363      * @author hegg
364      * @date 2017年11月6日 下午8:29:31
365      * @param keyWord 返回类型 void
366      */
367     public static void searchIndex(String keyWord) {
368         Date begin = new Date();
369         // 1、创建Analyzer词法分析器,注意SimpleAnalyzer和StandardAnalyzer的区别
370         Analyzer analyzer  = null;
371         // 2、创建索引在的文件夹
372         Directory indexDirectory = null;
373         // 3、创建DirectoryReader
374         DirectoryReader directoryReader = null;
375         try {
376 //            analyzer = new StandardAnalyzer();
377 //            analyzer = new SimpleAnalyzer();
378             analyzer = new IKAnalyzer(true);
379 //            indexDirectory = FSDirectory.open(new File(INDEX_DIR));
380             indexDirectory = FSDirectory.open(FileSystems.getDefault().getPath(INDEX_DIR));
381             directoryReader = DirectoryReader.open(indexDirectory);
382             // 3:根据DirectoryReader创建indexSeacher
383             IndexSearcher indexSearcher = new IndexSearcher(directoryReader);
384             // 4创建搜索用的query,指定搜索域
385 //            QueryParser parser = new QueryParser(, "content", analyzer);
386 //            Query query1 = parser.parse(keyWord);
387 //            ScoreDoc[] hits = indexSearcher.search(query1, null, 1000).scoreDocs;
388 //            for (int i = 0; i < hits.length; i++) {
389 //                Document hitDoc = indexSearcher.doc(hits[i].doc);
390 //                System.out.println("____________________________");
391 //                System.out.println(hitDoc.get("content"));
392 //                System.out.println(hitDoc.get("fileName"));
393 //                System.out.println(hitDoc.get("filePath"));
394 //                System.out.println(hitDoc.get("updateTime"));
395 //                System.out.println("____________________________");
396 //            }
397 
398             String[] fields = { "fileName", "content" }; // 要搜索的字段,一般搜索时都不会只搜索一个字段
399             // 字段之间的与或非关系,MUST表示and,MUST_NOT表示not,SHOULD表示or,有几个fields就必须有几个clauses
400             BooleanClause.Occur[] clauses = { BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD };
401             Query query2 = MultiFieldQueryParser.parse(keyWord, fields, clauses, analyzer);
402             // 5、根据searcher搜索并且返回TopDocs
403             TopDocs topDocs = indexSearcher.search(query2, 100); // 搜索前100条结果
404             System.out.println("共找到匹配处:" + topDocs.totalHits); // totalHits和scoreDocs.length的区别还没搞明白
405             ///6、根据TopDocs获取ScoreDoc对象
406             ScoreDoc[] scoreDocs = topDocs.scoreDocs;
407             System.out.println("共找到匹配文档数:" + scoreDocs.length);
408             QueryScorer scorer = new QueryScorer(query2, "content");
409             // 7、自定义高亮代码
410             SimpleHTMLFormatter htmlFormatter = new SimpleHTMLFormatter("<span style=\"backgroud-color:black;color:red\">", "</span>");
411             Highlighter highlighter = new Highlighter(htmlFormatter, scorer);
412             highlighter.setTextFragmenter(new SimpleSpanFragmenter(scorer));
413             for (ScoreDoc scoreDoc : scoreDocs) {
414                 ///8、根据searcher和ScoreDoc对象获取具体的Document对象
415                 Document document = indexSearcher.doc(scoreDoc.doc);
416                 System.out.println("-----------------------------------------");
417                 System.out.println(document.get("fileName") + ":" + document.get("filePath"));
418                 System.out.println(highlighter.getBestFragment(analyzer, "content", document.get("content")));
419                 System.out.println("-----------------------------------------");
420             }
421         } catch (IOException e) {
422             e.printStackTrace();
423         } catch (ParseException e) {
424             e.printStackTrace();
425         } catch (InvalidTokenOffsetsException e) {
426             e.printStackTrace();
427         } finally {
428             try {
429                 if (analyzer != null) analyzer.close();
430                 if (directoryReader != null) directoryReader.close();
431                 if (indexDirectory != null) indexDirectory.close();
432             } catch (Exception e) {
433                 e.printStackTrace();
434             }
435         }
436 
437         Date end = new Date();
438         System.out.println("查看关键字耗时:" + (end.getTime() - begin.getTime()) + "ms\n");
439     }
440 
441     public static void main(String[] args) throws Exception {
442         File fileIndex = new File(INDEX_DIR);
443         if (deleteDir(fileIndex)) {
444             fileIndex.mkdir();
445         } else {
446             fileIndex.mkdir();
447         }
448 
449         creatIndex();
450         searchIndex("天安门");
451     }
452 }
View Code
复制代码

 

  

 最后附上本例子用到的jar,下载地址链接:http://pan.baidu.com/s/1jI26UgQ 密码:qix6

<classpathentry kind="lib" path="F:/jar/poi常用jar包/dom4j-1.6.1.jar"/>
<classpathentry kind="lib" path="F:/jar/poi常用jar包/poi-3.9-20121203.jar"/>
<classpathentry kind="lib" path="F:/jar/poi常用jar包/poi-examples-3.9-20121203.jar"/>
<classpathentry kind="lib" path="F:/jar/poi常用jar包/poi-excelant-3.9-20121203.jar"/>
<classpathentry kind="lib" path="F:/jar/poi常用jar包/poi-ooxml-3.9-20121203.jar"/>
<classpathentry kind="lib" path="F:/jar/poi常用jar包/poi-ooxml-schemas-3.9-20121203.jar"/>
<classpathentry kind="lib" path="F:/jar/poi常用jar包/poi-scratchpad-3.9-20121203.jar"/>
<classpathentry kind="lib" path="F:/jar/poi常用jar包/stax-api-1.0.1.jar"/>
<classpathentry kind="lib" path="F:/jar/poi常用jar包/xmlbeans-2.3.0.jar"/>
<classpathentry kind="lib" path="F:/jar/读取pdfjar/pdfbox-1.8.9.jar"/>
<classpathentry kind="lib" path="F:/jar/读取pdfjar/FontBox-0.1.0.jar"/>
<classpathentry kind="lib" path="F:/jar/读取pdfjar/PDFBox-0.7.3.jar"/>
<classpathentry kind="lib" path="F:/jar/Lucene/Lucene7.1.0/lucene-analyzers-common-7.1.0.jar"/>
<classpathentry kind="lib" path="F:/jar/Lucene/Lucene7.1.0/lucene-core-7.1.0.jar"/>
<classpathentry kind="lib" path="F:/jar/Lucene/Lucene7.1.0/lucene-highlighter-7.1.0.jar"/>
<classpathentry kind="lib" path="F:/jar/Lucene/Lucene7.1.0/lucene-memory-7.1.0.jar"/>
<classpathentry kind="lib" path="F:/jar/Lucene/Lucene7.1.0/lucene-queries-7.1.0.jar"/>
<classpathentry kind="lib" path="F:/jar/Lucene/Lucene7.1.0/lucene-queryparser-7.1.0.jar"/>
<classpathentry kind="lib" path="F:/jar/Lucene/Lucene7.1.0/IKAnalyzer2012_FF.jar"/>

 

posted @   silentmuh  阅读(1326)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
Live2D
欢迎阅读『lucene7.1.0实现搜索文件内容』
  1. 1 Walk Thru Fire Vicetone
  2. 2 爱你 王心凌
  3. 3 Inspire Capo Productions - Serenity
  4. 4 Welcome Home Radical Face
  5. 5 粉红色的回忆 李玲玉
Walk Thru Fire - Vicetone
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : Van Der Voort, Joren Johannes

作曲 : Victor Pool/Justin Gammella/Ruben Christopher den Boer/Meron Mengist/Joren van der Voort

Talk to me

Spill the secrets you've been keeping

Life cuts deep

Let me help pick up the pieces

You're not alone, I'm by your side

Don't you know, don't you know

I'll walk through fire with you

I'll walk through fire

No matter what, I'll make it right

Don't you know, don't you know

I'll walk through fire with you

I'll walk through fire

I'm not an angel, I'm not a saint

I've been a closed book full of mistakes

But when you're broken, when you're in pain

Oooh, ooh

I'll walk through fire with you

I'll walk through fire

I'll walk through fire with you

I'll walk through fire

You know I

Don't pretend to be a savior

But let me in, yeah

I promise nobody can break us

You're not alone, I'm by your side

Don't you know, don't you know

I'll walk through fire with you

I'll walk through fire

No matter what, I'll make it right

Don't you know, don't you know

I'll walk through fire with you

I'll walk through fire

I'm not an angel, I'm not a saint

I've been a closed book full of mistakes

But when you're broken, when you're in pain

Oooh, ooh

I'll walk through fire with you

I'll walk through fire with you

I'll walk through fire

I'll walk through fire with you

I'll walk through fire with you

You're not alone, I'm by your side

Don't you know, don't you know

I'll walk through fire with you

I'll walk through fire

I'm not an angel, I'm not a saint

I've been a closed book full of mistakes

But when you're broken, when you're in pain

Oooh, ooh

I'll walk through fire with you

I'll walk through fire with you

I'll walk through fire

I'll walk through fire with you

I'll walk through fire with you

点击右上角即可分享
微信分享提示