Java FileInputStream内存不足问题

Java FileInputStream内存不足问题,java,memory,memory-management,out-of-memory,Java,Memory,Memory Management,Out Of Memory,我试图读取excel文件,然后使用xssf写入csv文件。内存不足错误(堆空间)。我看到fileinputstream有利于内存管理,但我仍然看到了这个问题 package xlsxtocsv; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException;

我试图读取excel文件,然后使用xssf写入csv文件。内存不足错误(堆空间)。我看到fileinputstream有利于内存管理,但我仍然看到了这个问题

package xlsxtocsv;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Locale;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class xlsxtocsv
{

    private static final String NEW_LINE_CHARACTER="\r\n";

    /**
     * Write the string into a text file 
     * @param csvFileName
     * @param csvData
     * @throws Exception
     */
    private static void writeCSV(String csvFileName,String csvData) throws Exception{
        FileOutputStream writer = new FileOutputStream(csvFileName);
        writer.write(csvData.getBytes());
        writer.close();
        System.out.println("Sucessfully written data to "+csvFileName);
    }


    public static void excelXToCSVfile(String excelFileName,String csvFileName,String Field_Delimiter,int Sheet_Number) {
         checkValidFile(excelFileName);
         XSSFWorkbook myWorkBook;
        try {
            myWorkBook = new XSSFWorkbook(new FileInputStream(excelFileName));

            XSSFSheet mySheet = myWorkBook.getSheetAt(Sheet_Number);
             String csvData="";
             DataFormatter formatter = new DataFormatter(Locale.US);
             checkValidFile(excelFileName);

             int rows = mySheet.getPhysicalNumberOfRows();
             String prefix="\"";

             for (int eachRow = 0;eachRow<rows;eachRow++) {
                 XSSFRow myRow = (XSSFRow) mySheet.getRow(eachRow);
                     for ( int i=0;i<myRow.getLastCellNum();i++){
                         if(i==0)
                         {

                             csvData += prefix+formatter.formatCellValue(myRow.getCell(i))+prefix;

                         }
                         else
                         {
                             csvData += Field_Delimiter+prefix+formatter.formatCellValue(myRow.getCell(i))+prefix;

                         }


                     }
                     csvData+=NEW_LINE_CHARACTER;
             }




                 try {
                    writeCSV(csvFileName, csvData);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



         }


    /**
     * get Cell value from XLSX file column
     * @param myCell
     * @return
     * @throws Exception
     */

        private static void checkValidFile(String fileName){
        boolean valid=true;
        try{
            File f = new File(fileName);
            if ( !f.exists() || f.isDirectory() ){
                valid=false;
            }
        }catch(Exception e){
            valid=false;
        }
        if ( !valid){
            System.out.println("File doesn't exist: " + fileName);
            System.exit(0);
        }
    }
    public static void main(String[] args) throws Exception
    {
        String inp_file_name="";
        String Output_file_name="";
        String delimiter=",";


        //inp_file_name=args[0];    
        //Output_file_name=args[1]; 

    enter code here
        //delimiter=args[2];


        inp_file_name="C:/Users/xxx/Desktop/cloudera_shared/test_data.xlsx";
        Output_file_name="C:/Users/xxx/Desktop/cloudera_shared/test_data.csv";
        delimiter="|";



    if(args.length==4 && (args[3].equals("") == false))
    {

        int Sheet_Number=Integer.parseInt(args[3]); 
        excelXToCSVfile(inp_file_name,Output_file_name,delimiter,Sheet_Number);


    }
    else
    {

        excelXToCSVfile(inp_file_name,Output_file_name,delimiter,0);
    }

    }

}
xlsxtocsv包;
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.FileNotFoundException;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.util.Locale;
导入org.apache.poi.ss.usermodel.DataFormatter;
导入org.apache.poi.xssf.usermodel.XSSFRow;
导入org.apache.poi.xssf.usermodel.xssfheet;
导入org.apache.poi.xssf.usermodel.xssf工作簿;
公共类xlsxtocsv
{
私有静态最终字符串NEW\u LINE\u CHARACTER=“\r\n”;
/**
*将字符串写入文本文件
*@param csvFileName
*@param csvData
*@抛出异常
*/
私有静态void writeCSV(字符串csvFileName,字符串csvData)引发异常{
FileOutputStream编写器=新的FileOutputStream(csvFileName);
writer.write(csvData.getBytes());
writer.close();
System.out.println(“成功地将数据写入”+csvFileName);
}
公共静态无效excelXToCSVfile(字符串excelFileName、字符串csvFileName、字符串字段\分隔符、整型工作表\编号){
checkValidFile(Excel文件名);
XSSF工作手册;
试一试{
My工作簿=新XSSF工作簿(新文件输入流(excelFileName));
XSSFSheet mySheet=myWorkBook.getSheetAt(工作表编号);
字符串csvData=“”;
DataFormatter formatter=新的DataFormatter(Locale.US);
checkValidFile(Excel文件名);
int rows=mySheet.getPhysicalNumberOfRows();
字符串前缀=“\”;

对于(int eachRow=0;eachRow,您可以像这样设置Java进程可用的堆内存的最大大小(这里我将它增加到1024MB)

如果运行
java-X
,可以看到不同的可用选项


尝试在探查器中运行您的程序,以便更好地了解哪些部分是内存密集型的。

我可以建议您解决代码之外的问题:

  • String csvData
    应替换为
    StringBuffer csvData
  • 您可以声明
    FileOutputStream(nameFile,true)
    (set append为true)
  • 您可以使用多线程执行两个任务:

    • 第一:从excel文件中读取内容
    • 第二:写出刚读过的内容

  • 假设您在始终安全的finally块中关闭了
    fileinputstream
    。请参阅此部分,这可能会有所帮助。“
    fileinputstream
    有助于内存管理"-是什么让你产生了这样的想法?这两个概念是不相关的。另外,为什么你要复制Excel已经做过的事情?Excel完全能够从xls文件中写入CSV。当执行writeCSV方法时,CsvData的长度是多少?我甚至尝试了3000m,但在FileOutputStream writer=new FileOutputStrea时,它说内存不足没有任何改进m(csvFileName);您的excel文件有多大?它只有35MB,我的系统有16GB的ram
    java -Xmx1024m -jar myProgram.jar