dlmread为大型文本文件返回单个列

时间:2012-08-17 17:46:12

标签: java file matlab

我正在尝试使用dlmread读取一个大文件,但它只是将整个文件视为一个长列。该文件使用Java编写,代码如下:

public void writeToFile(double[] arr) throws IOException{

FileWriter write = new FileWriter(path, append);
PrintWriter print_line = new PrintWriter(write);

for(int i=0; i<arr.length; i++){
  print_line.printf("%f\t", arr[i]);   
}
print_line.printf("\n");

print_line.close();

}

我的MATLAB脚本读取文件,如:[DATA] = dlmread('probability_cyclelength.dat');给出:

>>size(DATA)

ans =
         2000000        1 

总共有2000000个数据,每行最多60,000个(但每行数量不一样 - 无所谓)

当我尝试使用较小的数据集(100000数据)时,它可以正常工作。我不知道问题是在Java还是MATLAB中,所以我真的需要一些帮助,谢谢!

1 个答案:

答案 0 :(得分:6)

默认情况下dlmread尝试从文件中推断分隔符,默认情况下它使用空格作为分隔符。

我能够复制您描述的问题的唯一方法是将' '指定为分隔符。你确定你没有这样做吗?

尝试进行此更改,看看它是否解决了您的问题。

data = dlmread(inFile, '\t');

如果这不能解决您的问题,那么我怀疑问题是由于文本文件中的行具有不同的列数而引起的。例如,如果您使用dlmread打开包含以下内容的文本文件:

1 2 3 4
5

dlmread返回如下矩阵:

1 2 3 4
5 0 0 0

这种表示是浪费的,因为它使用64字节(每双8字节* 8双)来存储40字节的信息。

对于这些空位,可能是因为文件的矩阵表示太大,所以dlmread返回你的向量而不是节省内存。

你可以解决这个问题。如果您一次只需要几行,则可以通过指定rangedlmread来加载文件中的行集合。 注意要使其工作,您必须知道文件中的最大列数,因为dlmread不会让您阅读超过该列数。

r = [0 4]; %load the first 5 rows
maxC = 10; % load up to 10 columns
data = dlmread(inFile, '\t', [r(1), 0, r(2), maxX]);

然后你可以循环加载感兴趣的行的文件,但由于我之前提到的内存限制,你可能无法将它们全部加载到矩阵中。

如果您需要内存中的整个数据集,那么您应该考虑单独加载每一行并将它们保存到单元格数组中。让所有东西都加载需要更多的工作,但你可以用这样的东西做到这一点:

% open the file
fid = fopen(fileName); 
% load each line as a single string
tmp = textscan(fid, '%s', 'delimiter', '\n'); 
% textscan wraps its results in a cell, remove that wrapping
rawText = tmp{1}; 
nLines = numel(rawText);

%create a cell array to store the processed string
data = cell(nLines, 1);
for i = 1:nLines
  %scan a line of text returning a vector of doubles
  tmp = textscan(rawText{i}, '%f');
  data{i} = tmp{1}; 
end