4

我正在尝试使用 读取一个大文件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,所以我真的需要一些帮助,谢谢!

4

1 回答 1

6

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

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

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

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

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

1 2 3 4
5

dlmread返回一个这样的矩阵:

1 2 3 4
5 0 0 0

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

可能是由于这些空位置,您的文件的矩阵表示太大了,因此dlmread返回您的向量来节省内存。

你可以解决这个问题。如果您一次只需要几行,则可以通过指定 arange来从文件中加载行集合dlmread请注意,要使其正常工作,您必须知道文件中的最大列数,因为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
于 2012-08-17T18:35:15.887 回答