我不清楚为什么会收到此错误。我找不到任何方法来节省更多的内存。如果有人能帮助我提高效率,我们将不胜感激。 有人也可以查看我的代码,看看我做了什么傻事吗?提前谢谢。
MAIN CLASS
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.SpringLayout;
import javax.swing.JTextField;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.JButton;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class Main extends JFrame {
private JPanel contentPane;
private JTextField Searchq;
private JScrollPane scrollPane;
private static JTextArea txtpdisplay;
/**
* Launch the application.
*
* @throws IOException
*/
public static void filelistandfind(String find) throws IOException {
Files.walk(Paths.get("C:\\Users\\localness\\Desktop\\Locker")).forEach(
filePath -> {
if (Files.isRegularFile(filePath)) {
if (filePath.toString().endsWith(".docx")) {
try {
if (DocxCompair.Readfile(filePath.toString(),
find)) {
//System.out.println(filePath);
txtpdisplay.append(filePath.toString() + "\n");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main frame = new Main();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Main() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 646, 344);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
SpringLayout sl_contentPane = new SpringLayout();
contentPane.setLayout(sl_contentPane);
Searchq = new JTextField();
sl_contentPane.putConstraint(SpringLayout.NORTH, Searchq, 5,
SpringLayout.NORTH, contentPane);
sl_contentPane.putConstraint(SpringLayout.WEST, Searchq, 108,
SpringLayout.WEST, contentPane);
sl_contentPane.putConstraint(SpringLayout.SOUTH, Searchq, 36,
SpringLayout.NORTH, contentPane);
contentPane.add(Searchq);
Searchq.setColumns(10);
scrollPane = new JScrollPane();
sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane, 3, SpringLayout.SOUTH, Searchq);
sl_contentPane.putConstraint(SpringLayout.WEST, scrollPane, 5, SpringLayout.WEST, contentPane);
sl_contentPane.putConstraint(SpringLayout.SOUTH, scrollPane, -9, SpringLayout.SOUTH, contentPane);
sl_contentPane.putConstraint(SpringLayout.EAST, scrollPane, -5, SpringLayout.EAST, contentPane);
sl_contentPane.putConstraint(SpringLayout.EAST, Searchq, 0,
SpringLayout.EAST, scrollPane);
contentPane.add(scrollPane);
txtpdisplay = new JTextArea();
txtpdisplay.setText("");
scrollPane.setViewportView(txtpdisplay);
JButton Search = new JButton("Search");
Search.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
try {
filelistandfind(Searchq.getText());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
sl_contentPane.putConstraint(SpringLayout.NORTH, Search, 2, SpringLayout.NORTH, Searchq);
sl_contentPane.putConstraint(SpringLayout.WEST, Search, 0, SpringLayout.WEST, scrollPane);
sl_contentPane.putConstraint(SpringLayout.SOUTH, Search, -3, SpringLayout.SOUTH, Searchq);
sl_contentPane.putConstraint(SpringLayout.EAST, Search, -6, SpringLayout.WEST, Searchq);
contentPane.add(Search);
}
}
DocxCompair类
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
import java.util.zip.ZipInputStream;
public final class DocxCompair {
private static byte[] buffer = new byte[204800];
private static String result;
private static int len;
/*
* public static void main(String[] args) throws IOException { String s =
* "Stuart.docx"; String n = "<#tag>"; FileInputStream is = new
* FileInputStream(s); ZipInputStream zis = new ZipInputStream(is);
* System.out.println(Readfile(s, n)); }
*/
private static boolean extractFile(ZipInputStream zipIn, String filePath,
String text) throws IOException {
result = "";
len = 0;
while ((len = zipIn.read(buffer)) > 0) {
// System.out.print(new String(buffer));
System.gc();
result += result + new String(buffer);
}
// System.out.println();
if (result.contains(text)) {
return true;
} else {
return false;
}
}
private static String texttag;
private static String fileName;
private static ZipInputStream zip;
public static boolean Readfile(String names, String text)
throws FileNotFoundException {
// TODO Auto-generated method stub
fileName = names;
zip = new ZipInputStream(new FileInputStream(fileName));
try {
String name;
while (true) {
try {
name = zip.getNextEntry().getName();
// System.out.println(name);
if (name.startsWith("word/document.xml")) {
// System.out.println(name);
texttag = text;
texttag = texttag.replace(">", ">");
texttag = texttag.replace("<", "<");
// System.out.println(texttag);
if (extractFile(zip, name, texttag)) {
return true;
} else {
return false;
}
}
} catch (NullPointerException a) {
// a.printStackTrace();
return false;
// break;
}
}
// System.out.println("Done");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
}
}
错误讯息:
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(Unknown Source)
at java.lang.AbstractStringBuilder.append(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at DocxCompair.extractFile(DocxCompair.java:26)
at DocxCompair.Readfile(DocxCompair.java:58)
at Main.lambda$0(Main.java:37)
at Main$$Lambda$17/772250001.accept(Unknown Source)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
at java.util.Iterator.forEachRemaining(Unknown Source)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source)
at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
at java.util.stream.ReferencePipeline.forEach(Unknown Source)
at Main.filelistandfind(Main.java:32)
at Main$2.mouseClicked(Main.java:106)
at java.awt.AWTEventMulticaster.mouseClicked(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
答案 0 :(得分:4)
你正在建造一个巨大的巨型弦。看看你的代码:
result = "";
len = 0;
while ((len = zipIn.read(buffer)) > 0) {
// System.out.print(new String(buffer));
System.gc();
result += result + new String(buffer);
}
让我们说我一次只读2个字节。以下是此代码的用途。
result = ab // empty + empty + new stuff
result = ababcd // result + result + new stuff.
result = ababcdababcdef // result + result + new stuff
result = ababcdababcdefababcdababcdefgh // result + result + new stuff
每当你读取一个200k的块时,你的结果大小加倍,然后加上200k。这意味着2mb文件的 (10次读取200k)你的结果实际上超过了204mb。
原因是因为你在做result += result + new String(buffer);
你应该做result += new String(buffer)
OR,最好是使用StringBuffer并在阅读时附加到它。
StringBuffer result = new StringBuffer();
len = 0;
while ((len = zipIn.read(buffer)) > 0 ) {
result.append( new String(buffer));
}
答案 1 :(得分:0)
首先,你不能完全关闭所有资源。
其次,你可以尝试几件事。
首先,您可以使用名为Files.find()
的方法。试试这个:
private static final BiPredicate<Path, BasicFileAttributes> DOCX_FILES
= (path, attrs) -> attrs.isRegularFile
&& path.getFileName().toString().endsWith(".docx");
final Path basePath = Paths.get("C:\\Users\\localness\\Desktop\\Locker");
try (
final Stream<Path> stream = Files.find(basePath, Integer.MAX_VALUE, DOCX_FILES);
) {
stream.forEach(path -> whatever)
}
请注意,我在这里关闭了流。
现在,您想要做的就是将zipx文件作为zip打开,并阅读名为word/document.xml
的条目的内容。再次使用JSR 203:
final URI uri = URI.create("jar:" + docxPath.toUri());
try (
final FileSystem zipfs = FileSystems.newFileSystem(uri, Collections.emptyMap());
final Reader reader = Files.newBufferedReader(zipfs.getPath("word/document.xml"),
StandardCharsets.UTF_8);
) {
// use the reader
} catch (FileNotFoundException ignored) {
// no such file in zip
}