我正在尝试从文本文件中提取特定数据。我使用bufferreader逐行读取文件,这样我就可以处理该行。
以下是我写的代码:
File CAD = new File (filename);
try (FileReader fileReader = new FileReader(CAD))
{
String bn = CAD.getName();
String[] bn2 = bn.split("\\.");
BOARD_NAME= bn2[0];
StringBuilder PACKAGE = new StringBuilder(),
GRAPHIC = new StringBuilder(),
PADS_DIA = new StringBuilder(),
PADS = new StringBuilder(),
COMPONENTS = new StringBuilder();
try (BufferedReader bufferedReader = new BufferedReader(fileReader))
{
String line;
while ((line = bufferedReader.readLine()) != null)
{
if (line.startsWith("J!"))
{
String[] units = line.split("!");
UNITS = units[8];
}
else if (line.startsWith("A!REFDES!COMP_CLASS!"))
{
while (!"A!NET_NAME!REFDES!PIN_NUMBER!PIN_NAME!PIN_GROUND!PIN_POWER!".equals(line = bufferedReader.readLine()))
{
if (line.startsWith("S!"))
{
String[] data = line.split("!");
COMPONENTS.append(data[1])
.append("!")
.append(data[8])
.append("!")
.append(data[10])
.append("!")
.append(data[11])
.append("!")
.append(data[12])
.append("\n");
}
}
}
else if (line.startsWith("A!PAD_NAME"))
{
do
{
if (line.startsWith("S!") && line.contains("00001"))
{
String[] data = line.split("!");
if ("CIRCLE".equals(data[6]))
{
PADS.append(data[1])
.append("!C!")
.append(data[7])
.append("!")
.append(data[8])
.append("!TOP")
.append("\n");
}
else if (data[6].equals(""))
{
PADS.append(data[1])
.append("!0!")
.append(data[7])
.append("!")
.append(data[8])
.append("!TOP")
.append("\n");
}
else
{
PADS.append(data[1])
.append("!R!")
.append(data[7])
.append("!")
.append(data[8])
.append("!TOP")
.append("\n");
}
}
else if (line.startsWith("S!") && line.contains("BOTTOM"))
{
String[] data = line.split("!");
if ("CIRCLE".equals(data[6]))
{
PADS.append(data[1])
.append("!C!")
.append(data[7])
.append("!")
.append(data[8])
.append("!BOTTOM")
.append("\n");
}
else if (data[6].equals(""))
{
PADS.append(data[1])
.append("!0!")
.append(data[7])
.append("!")
.append(data[8])
.append("!BOTTOM")
.append("\n");
}
else
{
PADS.append(data[1])
.append("!R!")
.append(data[7])
.append("!")
.append(data[8])
.append("!BOTTOM")
.append("\n");
}
}
else if (line.startsWith("S!") && line.contains("~DRILL"))
{
String[] data = line.split("!");
PADS_DIA.append(data[1])
.append("!")
.append(data[6])
.append("\n");
}
}while (!"A!GRAPHIC_DATA_NAME!GRAPHIC_DATA_NUMBER!RECORD_TAG!GRAPHIC_DATA_1!GRAPHIC_DATA_2!GRAPHIC_DATA_3!GRAPHIC_DATA_4!GRAPHIC_DATA_5!GRAPHIC_DATA_6!GRAPHIC_DATA_7!GRAPHIC_DATA_8!GRAPHIC_DATA_9!SUBCLASS!SYM_NAME!REFDES!".equals(line = bufferedReader.readLine()));
}
if (line.startsWith("A!SYM_NAME!"))
{
int k =0,j=0;
String[] data1 = line.split("!");
for (int i =0; i<data1.length;i++)
{
if (data1[i].equals("PIN_NUMBER"))
{
k=i;
}
else if (data1[i].equals("PIN_ROTATION"))
{
j=i;
}
}
while(!"A!VIA_X!VIA_Y!PAD_STACK_NAME!NET_NAME!TEST_POINT!".equals(line = bufferedReader.readLine()))
{
if (line.startsWith("S!"))
{
String[] data = line.split("!");
if (data[8].equals("")||data[8]==null)
{}
else
{
PACKAGE.append(data[1])
.append("!")
.append(data[k])
.append("!")
.append(data[k+1])
.append("!")
.append(data[k+2])
.append("!")
.append(data[k+3])
.append("!")
.append(data[k+4])
.append("!")
.append(data[j])
.append("\n");
}
}
}
}
else if (line.startsWith("A!CLASS!SUBCLASS!GRAPHIC_DATA_NAME!"))
{
while (!"A!SUBCLASS!PAD_SHAPE_NAME!GRAPHIC_DATA_NAME!GRAPHIC_DATA_NUMBER!RECORD_TAG!GRAPHIC_DATA_1!GRAPHIC_DATA_2!GRAPHIC_DATA_3!GRAPHIC_DATA_4!GRAPHIC_DATA_5!GRAPHIC_DATA_6!GRAPHIC_DATA_7!GRAPHIC_DATA_8!GRAPHIC_DATA_9!PAD_STACK_NAME!REFDES!PIN_NUMBER!".equals(line = bufferedReader.readLine()))
{
if (line.startsWith("S!BOARD GEOMETRY!OUTLINE"))
{
//to find the diamension x and y of board
String data[]=line.split("!");
double valuex = Double.parseDouble(data[6]);
double valuey = Double.parseDouble(data[7]);
PANEL_X.add(valuex);
PANEL_Y.add(valuey);
}
else if (line.startsWith("S!REF DES"))
{
String data[] = line.split("!");
if (data[2].equals("ASSEMBLY_TOP")||data[2].equals("DISPLAY_TOP"))
{
GRAPHIC.append(data[12])
.append("!")
.append("TOP")
.append("\n");
}
else if(data[2].equals("ASSEMBLY_BOTTOM")||data[2].equals("DISPLAY_BOTTOM"))
{
GRAPHIC.append(data[12])
.append("!")
.append("BOTTOM")
.append("\n");
}
}
}
double max_x = max(PANEL_X);
double min_x = min(PANEL_X);
double max_y = max(PANEL_Y);
double min_y = min(PANEL_Y);
double diamensionx = max_x - min_x;
double diamensiony = max_y - min_y;
MIN_X = min_x;
MIN_Y = min_y;
BOARD_X = diamensionx;
BOARD_Y = diamensiony;
BOARD_Z = 62.9921;
}
ArrayList<String> $TEMP_LIST = new ArrayList<>(asList(GRAPHIC.toString().split("\n")));
HashSet<String> graphic = new HashSet<>($TEMP_LIST);
GRAPHIC_LIST = new ArrayList<>(graphic);
PACKAGE_LIST = new ArrayList<>(asList(PACKAGE.toString().split("\n")));
PADS_LIST = new ArrayList<>(asList(PADS.toString().split("\n")));
PADS_DIA_LIST = new ArrayList<>(asList(PADS_DIA.toString().split("\n")));
COMPONENTS_LIST = new ArrayList<>(asList(COMPONENTS.toString().split("\n")));
}
}
fileReader.close();
}
在我的代码中,仍然有很多if else
条件。当我尝试从大约20MB的文件大小中提取时,需要30秒的时间。但是当我尝试读取大约200MB的文件大小时,需要很长时间,比如超过30分钟。我的朋友建议我使用MappedByteBuffer
更快地处理。
我还是Java新手。那么MappedBuffer
在这种情况下的执行速度是否比BufferReader
更快?如果是,我如何逐行处理数据?
答案 0 :(得分:1)
我怀疑你的问题是BufferedReader
,它几乎可以用于所有目的。使用MappedByteBuffer
确实允许您一次性将文件的内容(或部分内容)读入内存,但之后您正在处理ByteBuffer
而不是文本行,并且你不太可能通过它获得显着的性能提升。
如果你删除了while循环的内容并且只是在没有任何处理的情况下读取了这些行,你就会注意到瞬间读取了一个20MB的文件。
明显(次要)改进是将line.split("!")
移动到实际需要的范围内。我不确定您显示的代码是否是您的实际代码(可能不是因为您将split()
拼写为splits()
,但在示例代码中您只需要拆分如果它以cga
开头。如果没有看到您的实际代码,很难指出使其变慢的所有位置(当然您可以使用分析器)。
作为最后一个建议,如果您正在专业地编写Java,那么您可能希望避免使用变量名中的$
等非Java内容,并在自己的行中打开大括号(Java遵循{{ 3}})。它对可能阅读您代码的其他Java开发人员很有帮助。
答案 1 :(得分:1)
如果没有分析,这很难正确回答。 有一点可能值得尝试:
每行使用String.split
。对于split
的每次调用,Java都会编译一个模式:
public String[] split(String regex, int limit) {
return Pattern.compile(regex).split(this, limit);
}
因此,编译一开始只使用一次的模式可能会更好:
Pattern pattern = Pattern.compile("!");
Pattern patternNL = Pattern.compile("\n");
并使用它来分割你的字符串:
String[] parts = pattern.split(line);
String[] singleLines = patternNL.split(lines);
答案 2 :(得分:0)
不一定更快;只有当您的文本文件大小为100 MB时,您才会考虑这样的事情。
最好先做其他优化。
赞new StringBuilder(10_000)
。也适用于BufferedReader。