我需要索引整个文件系统,然后转换为xml。所以我创建了代码,但它产生了内存不足错误(堆)。所以我的问题是如何避免这个错误。是因为创建了File1对象还是向量太匹配我已经设置了虚拟内存,但它又在973处产生了错误。
`
import java.util.Vector;
import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
public class Filewalk {
Vector<File1> vs= new Vector<File1>();
public void walk( String path ) {
File root = new File( path );
File[] list = root.listFiles();
if (list == null) return;
for ( File f : list ) {
if ( f.isDirectory() ) {
walk( f.getAbsolutePath() );
}
else {
File1 fv=new File1(f.getAbsoluteFile().toString(),f.length()); --we could change for the next string--
//mainRootElement.appendChild(getFile (doc, num++, f.getName(), f.length(), f.getAbsoluteFile());//
}
}
}
public static void main(String[] args) throws Exception {
Filewalk fw = new Filewalk();
File [] disks = File.listRoots();
for ( File d : disks )
fw.walk(d.toString());
//ByteArrayInputStream baos = new ByteArrayInputStream();
//ObjectInputStream oos = new ObjectInputStream(baos);
//oos.writeObject(fw.vs);
//oos.close();
}
}
class File1 {
File1 (String path1, long size1)
{ this.path=path1; this.size=size1;}
String path;
long size;}
`
Exception in thread "main" `java.lang.OutOfMemoryError: Java heap space
at java.io.WinNTFileSystem.list(Native Method)
at java.io.File.list(File.java:973)
at java.io.File.listFiles(File.java:1051)
at listing.Filewalk.walk(Filewalk.java:8)
at listing.Filewalk.walk(Filewalk.java:12)
at listing.Filewalk.walk(Filewalk.java:12)
at listing.Filewalk.walk(Filewalk.java:12)
at listing.Filewalk.walk(Filewalk.java:12)
at listing.Filewalk.main(Filewalk.java:24)
我尝试创建这个大向量,将其传递给swing Jtable,以显示文件的至少一部分(自动编号,名称,大小,路径)。无论如何在uindexing期间我需要分配这个唯一的数字并将其保存到某个东西。也许我需要通过添加记录来直接写入JDBC表来解除内存问题?无论如何如果我想将这些属性转换为xml标签,我还需要保存这个大的xml文件,以便在其中按名称搜索这些文件。如何解决这个问题?是不是所有File1的矢量都正确的想法?整个索引可以占用多少空间?
答案 0 :(得分:0)
我们可以提出类似的建议。我刚刚添加了上述代码的插入记录。它是通过将每个文件属性添加到创建的数据库来避免内存崩溃。但我不知道我们可以在SQL STATEMENT中使用变量。特别是通过使用f.method()这样的方法创建的。我可以避免复杂性,我们可以从第二个代码中寻求方法 - 一个用于创建数据库和表,另一个用于插入记录,这样我们就可以包含方法。 因为我不知道如何正确地塑造try并捕获这些JDBC代码的规则。
`import java.sql.*;
import java.io.File;
public class Filewalk {
int i=0;
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost/STUDENTS";
static final String USER = "root";
static final String PASS = "";
Connection conn = null;
Statement stmt = null;
//STEP 2: Register JDBC driver
Class.forName("com.mysql.jdbc.Driver");
//STEP 3: Open a connection
System.out.println("Connecting to a selected database...");
conn = DriverManager.getConnection(DB_URL, USER, PASS);
System.out.println("Connected database successfully...");
//STEP 4: Execute a query
System.out.println("Creating table in given database...");
stmt = conn.createStatement();
String sq = "CREATE DATABASE FILESS";
stmt.executeUpdate(sq);
String sql1 = "CREATE TABLE SYSTEM1 " +
"(id INTEGER not NULL, " +
" name VARCHAR(255), " +
" path VARCHAR(255), " +
" size INTEGER, " +
" PRIMARY KEY ( id ))";
stmt.executeUpdate(sql1);
public void walk( String path ) {
File root = new File( path );
File[] list = root.listFiles();
if (list == null) return;
for ( File f : list ) {
if ( f.isDirectory() ) {
walk( f.getAbsolutePath() );
}
else {
String sql2 = "INSERT INTO SYSTEM1" +
"VALUES (i++,f.getName(), f.getAbsoluteFile().toString(),f.length())";
stmt.executeUpdate(sql2);
}
}
try{
if(stmt!=null)
conn.close();
}catch(SQLException se){
}// do nothing
try{
if(conn!=null)
conn.close();
}catch(SQLException se){
se.printStackTrace();
}//end finally try
}//end try
System.out.println("Goodbye!");
}//end main
}
public static void main(String[] args) {
Filewalk fw = new Filewalk();
File [] disks = File.listRoots();
for ( File d : disks )
fw.walk(d.toString());
}
}
`
答案 1 :(得分:0)
人们告诉我错误的原因是什么?
简单。您的应用程序正在尝试使用比JVM更多的堆内存。那是因为它试图创建一个包含文件系统中所有文件信息的巨大内存Vector
。
此应用在停止之前可以处理多少个文件,
这取决于堆的大小。这又取决于Java堆大小参数。阅读java
命令的手册条目,注意-xmx
和-xms
参数。
然而,这并没有解决问题。无论你创建多大的堆,如果文件系统足够大,你的应用程序就会崩溃。将所有数据加载到大Vector
中的方法不起作用。周期。
相反,您应该根据需要通过查询树遍历结果的数据库来实现您自己的自定义TableModel
类,并且不会保持该类使用后的内存信息。
但即使这是一个坏主意(IMO)。将文件系统显示为具有数千或数百万条目的可滚动2-D表是一种可怕的UI设计。更好的想法是使用JTree
...使用合适的延迟加载&#34;模型&#34;避免构建庞大的内存数据结构的类。
更好的是,使用像JFileChooser
这样的现有文件树小部件......并且不要重新发明轮子。