当前位置: 首页 > 面试题库 >

如何以Scala方式解析基于行的文本文件(.mht)?

景理
2023-03-14
问题内容

我想使用scala解析.mht文件,但是我发现我的代码与Java完全一样。

以下是mht文件样本:

From: <Save by Tencent MsgMgr>
Subject: Tencent IM Message
MIME-Version: 1.0
Content-Type:multipart/related;
    charset="utf-8"
    type="text/html";
    boundary="----=_NextPart_20CAFF23_6090_43fc_8C0A.EE179EE81D19"

------=_NextPart_20CAFF23_6090_43fc_8C0A.EE179EE81D19
Content-Type: text/html
Content-Transfer-Encoding:7bit

<html xmlns="http://www.w3.org/1999/xhtml"><head></head>...</html>

------=_NextPart_20CAFF23_6090_43fc_8C0A.EE179EE81D19
Content-Type:image/jpeg
Content-Transfer-Encoding:base64
Content-Location:{64172C34-99E7-40f6-A933-3DDCF670ACBA}.dat

/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMU
FRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU
FBQUFBQUFBT/wAARCAJwA7sDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUF
BAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVW
V1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi

------=_NextPart_20CAFF23_6090_43fc_8C0A.EE179EE81D19
Content-Type:image/jpeg
Content-Transfer-Encoding:base64
Content-Location:{64172C34-99E7-40f6-A933-3DDCF670ACBA}.dat

/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMU
FRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU
FBQUFBQUFBT/wAARCAJwA7sDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUF
BAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVW
V1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi

------=_NextPart_20CAFF23_6090_43fc_8C0A.EE179EE81D19
Content-Type:image/jpeg
Content-Transfer-Encoding:base64
Content-Location:{64172C34-99E7-40f6-A933-3DDCF670ACBA}.dat

/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMU
FRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU
FBQUFBQUFBT/wAARCAJwA7sDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUF
BAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVW
V1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi

------=_NextPart_20CAFF23_6090_43fc_8C0A.EE179EE81D19

有一个名为的特殊行boundary,它是分隔符行:

------=_NextPart_20CAFF23_6090_43fc_8C0A.EE179EE81D19

第一部分是有关此文件的一些信息,可以忽略。以下是4个块,第一个是html文件,其他是jpg带有base64编码文本的图像。

如果我使用Java,则代码如下:

BufferedReader reader = new BufferedReader(new FileInputStream(new File("test.mht")))
String line = null;

String boundary = null;

// for a block
String contentType = null;
String encoding = null;
String location = null;
List<String> data = null;

while((line=reader.readLine())!=null) {
    // first, get the boundary
    if(boundary==null) {
        if(line.trim().startsWith("boundary=\"") {
             boundary = substringBetween(line, "\"", "\"");
        }
        continue;
    }

    if(line.equals("--"+boundary) { // new block
        if(contentType!=null) {
           // save data to a file
        }
        encoding=null;
        contentType=null;
        location = null;
        data = new ArrayList<String>();
    } else {
        if(id==null || contentType==null || location ==null) {
            if(line.trim().startsWith("Content-Type:") { /* get content type */ }
            // else check encoding
            // else check location
        } else {
            data.add(line);
        }
    }
}

我尝试使用scala重写代码,但是我发现我的代码结构几乎相同,只是我使用了scala语法而不是Java。

是否有scala方法来完成相同的工作?

PS:由于文件很大,因此我不想将整个文件加载到内存中。相反,我想逐行读取和解析它。

感谢您的帮助!


问题答案:

这可能是状态机的一个非常简单的用例。

import collection.mutable.ListBuffer
case class Part(contentType:Option[String], encoding:Option[String], location:Option[String], data:ListBuffer[String])

var boundary: String = null

val Boundary = """.*boundary="(.*)"""".r
var state = 0
val IN_PART = 1
val IN_DATA = 2

var _contentType:Option[String] = None
var _encoding:Option[String] = None
var _location:Option[String] = None
var _data = new ListBuffer[String]()

Source.fromFile("test.mht").getLines.foreach{
  case Boundary(b) => boundary = b
  case `boundary` => 
    _contentType = None
    _encoding = None
    _location = None
    _data = new ListBuffer[String]()    
    state = IN_PART
  case "" => state match {
    case IN_PART => state = IN_DATA
    case IN_DATA => 
        var currentPart = Part(_contentType, _encoding, _location, _data)
        /* deal with current Part as allData.last */
    case _ =>
  }
  case line => state match {
    case IN_DATA => _data.append(line)            
    case IN_PART => line.split(":") match {
      case Array("Content-Type", t) => _contentType = Some(t)
      case Array("Content-Transfer-Encoding", e) => _encoding = Some(e)
      case Array("Content-Location", l) => _location = Some(l)
      case _ =>
    }
  }
}


 类似资料:
  • #include <stdio.h> typedef struct { int a; int b; int c; int d; }ex_st; int main(void) { ex_st st = {1, 2, 3, 4}; printf("%d,%d,%d,%d\n", st.a, st.b,

  • 问题内容: 我有一个看起来像这样的日志文件(简化) Logline样本 我想提取 数据中 包含的json 并创建两个字段,一个用于名字,一个用于姓氏。但是,我得到的输出是这样的: 如你看到的 那不是我所需要的,我需要在kibana中为firstname和lastname创建字段,但是logstash不会使用json过滤器提取字段。 LogStash配置 非常感谢任何帮助,我敢肯定我错过了一些简单的

  • 问题内容: 我有一个包含以下行的文本文件: 每个“ |” 符号表示它有一列。我必须从“ |”内部的每一行中提取信息 迹象。当我尝试以下代码时: 它给了我: 如何正确解析? 问题答案: 试试这个:

  • 问题内容: 我正在寻找一种将复杂文本文件解析为pandas DataFrame的简单方法。下面是一个示例文件,我希望解析后的结果是什么样,以及我当前的方法。 有什么方法可以使其更简洁/更快/更pythonic /更易读? 我也把这个问题放在了Code Review上 。 我最终写了一篇博客文章向初学者解释。 这是一个示例文件: 这是我希望解析后的结果看起来像什么: 这是我目前解析的方式: 问题答案

  • 我意识到这个问题有点复杂,但我本质上想解析一个ANTLR4语法(一个实际的.g4文件),然后根据语法生成文档和其他工件(不是语法实例)。 例如,考虑包含以下规则的示例Java语法: 我希望能够解析Java。g4文件并生成说明“编译单元包含可选的packageDeclaration、0个或多个importDeclarations和0个或多个typeDeclarations”的文档。或者,我可能希望生

  • 问题内容: 我想解析这个XML文件: 要解析的XML文件: 我想将要点名称和方案返回给我。因此,对于示例文件,我想要AbsoluteValue和场景列表(CALCULATED和INPUT_IS_BLANK)。如果我错了,请纠正我,但是要使用的数据结构是 如何在Java代码中完成此操作?如果可能的话,我想使用XPATH。 我以为这是获取每个SCENARIO的正确XPATH表达式? 问题答案: 感谢M