How to indicate to the end of file in matlab - matlab

I have a flat file saved in binary format, i want to seek to specific byte and read untile the end of that file, so we need a condition for that, what is the condition that indicates the end of the file?
By the way, i don't want to load the whole file just open the file and seek to the position i need then read until to the end of the file...

MATLAB's fread function (and, indeed, the other file IO functions) will automatically detect the end of a binary file; there's no need for a special end-of-file marker.
fread documentation
General MATLAB IO documentation

You can use feof to test for the end of a file. For example, to read a file one character at a time:
fid = fopen('bench.dat');
k = 0;
while ~feof(fid)
curr = fscanf(fid,'%c',1);
if ~isempty(curr)
k = k+1;
benchstr(k) = curr;
end
end
fclose(fid);

You can pass Inf for the size argument when using the FREAD function (will read until end of file). Here is an example:
%# first lets create a simple binary file
fid = fopen('file.bin', 'wb');
fwrite(fid, 'hello world', 'char*1');
fclose(fid);
%# now open binary file, seek to some position, and read bytes till EOF
fid = fopen('file.bin', 'rb');
fseek(fid, 6, 'bof'); %# go to the 7th byte
B = fread(fid, Inf, 'uint8=>char'); %# read bytes until end-of-file (as chars)
fclose(fid);
disp(B)

Related

Copy specific lines from text file to create a new one

I have created a function that allows copying a number of lines from a text file and create a new file, let's say I want to take only the data contained between $$ElmLodlv and $$ElmNet.
Here is the code
fID = fopen(fileName,'r');
tline=fgetl(fID) ;
while isempty (strfind(tline,'$$ElmLodlv'))
tline=fgetl(fID) ;
end
buffer = fread(fID,Inf) ;
fclose(fID) ;
fID=fopen(newFileName,'w');
fwrite(fID, buffer) ;
fclose(fID);
end
The thing is that I don't really know how can I stop my buffer in the line corresponding to $$ElmNet, In other words my function creates a new file from $$ElmLodlv to the end of the file.
Any ideas how can do this?
What about an alternative to fread(fID,Inf):
buffer=0;
while ~feof(fID)
tline=fgetl(fID);
if ~isempty (strfind(tline,'$$ElmNet'))
break;
end
buffer(end+1:end+2+length(tline))=[tline 13 10];
end;
buffer=buffer(2:end);
Note that [13 10] equals to \n in the code above.
hope it helps!

Change text line in a file by using Matlab

So I have to modify a .dxf file (an Autocad file) by changing some data in it for another one we choose previously. Changing some lines of a .txt file in Matlab is not pretty difficult.
However, I cannot change a specific line when the new input's length is larger than the old one.
This is what I have and I want to change only 1D57:
TEXT
5
1D57
330
1D52
100
AcDbEntity
8
0
If I have as an input BBBB, everything goes right since both strings have the same length. The same does not apply when I try with BBBBbbbbbbbbbb:
TEXT
5
BBBBbbbbbbbbbb2
100
AcDbEntity
8
0
It deletes everything after it until the string stops. It happens the same when the input is shorter: it does not change the line for the new string but it writes until the new input stops. For example, in our case with AAA as an input, the result would be AAA7.
This is basically the code I am using to modify the file:
fID = fopen('copia.dxf','r+');
for i = 1:2
LineToReplace = TextIndex(i);
for k = 1:((LineToReplace) - 1);
fgetl(fID);
end
fseek(fID, 0, 'cof');
fprintf (fID, [Data{i}, '\n']);
end
fclose(fID);
You need to overwrite at least the rest of the file in order to change it (unless exact number of characters is replaced), as explained in jodag's comment. For instance,
% String to change and it's replacement
% (can readily be automated for more replacements)
str_old = '1D52';
str_new = 'BBBBbbbbbbbbbb';
% Open input and output files
fIN = fopen('copia.dxf','r');
fOUT = fopen('copia_new.dxf','w');
% Temporary line
tline = fgets(fIN);
% Read the entire file line by line
% Write it to the new file
% Replace str_old with str_new when encountered - note, if there is more
% than one occurence of str_old in the file all will be replaced - this can
% be handled with a proper flag
while (ischar(tline))
% char(10) is MATLAB's newline character representation
if strcmp(tline, [str_old, char(10)])
fprintf(fOUT, '%s \n', str_new);
else
% No need for \n - it's already there as we're using fgets
fprintf(fOUT, '%s', tline);
end
tline = fgets(fIN);
end
% Close the files
fclose(fIN);
fclose(fOUT);
% Copy the new file into the original
movefile 'copia_new.dxf' 'copia.dxf'
In practice, it is often far easier to simply overwrite the whole file.
As written in the notes - this can be automated for more replacements and it would also need an additional flag to only replace a given string once.

Appending data to a file in Matlab, removing before a symbol

I have a file which is written via Matlab from a vector M with binary data values. This file is written with Matlab's fwrite in the following script myGenFile.m of the form function myGenFile(fName, M):
% open output file
fId = fopen(fName, 'W');
% start by writing some things to the file
fprintf(fId, '{DATA BITLENGTH:%d}', length(M));
fprintf(fId, '{DATA LIST-%d:#', ceil(length(M) / 8) + 1);
% pad to full bytes
lenRest = mod(length(M), 8);
M = [M, zeros(1, 8 - lenRest)];
% reverse order in bytes
M = reshape(M, 8, ceil(length(M) / 8));
MReversed = zeros(8, ceil(length(M) / 8));
for i = 1:8
MReversed(i,:) = M(9-i,:);
end
MM = reshape(MReversed, 1, 8*len8);
fwrite(fId, MM, 'ubit1');
% write some ending of the file
fprintf(fId, '}');
fclose(fId);
Now I want to write a file myAppendFile.m, which appends some values to the existing file and has the following form: function myAppendFile(newData, fName). To do this I will have to remove the trailing '}':
fId = fopen(nameFile,'r');
oldData = textscan(fId, '%s', 'Delimiter', '\n');
% remove the last character of the file; aka the ending '}'
oldData{end}{end} = oldData{end}{end}(1:end-1);
The problem is now when trying to write oldData into the file (writing newData should be trivial, since it is also a vector of binary data like M), since it is a cell of cell arrays, containing strings.
How could I overcome this issue and append the new data correctly?
Instead of using textscan which copies the file to your memory, then writes it back, you could use fseek to set the pointer where you want to continue writing. Just put it one char before end of file and continue writing.
fseek(fid, -1, 'eof');

Reading a line of binary file MATLAB

I am new in using MATLAB and I want to do a simple thing: I want to read a binary file that contains rows like this
32156432
345243867
454154351
35477
5641871
....
I know that the fread() in MATLAB reads the file byte by byte, but I want to read the value that there is on each line. All values are uint32_t and the file is generated with a script in C++ with just a printf, the values are printed in a file like my_file.bin launching the executable in this way ./executable param1 >> my_file.bin
You can use the function fscanf
Sample Code:
fileID = fopen('my_file.bin','w');
x = 32156432;
y = 345243867;
w = 454154351;
fprintf(fileID, '%d\n',x);
fprintf(fileID, '%d\n',y);
fprintf(fileID, '%d\n',w);
fclose(fileID);
fileID = fopen('my_file.bin','r');
formatSpec = '%d';
A = fscanf(fileID, formatSpec);

Remove Characters from EOF while Writing to File in Matlab

In Matlab, after creating a certain number of lines and printing them to a file, I have the need to delete a line and rewrite the rest of the data to that same file. When I do so, the new data overwrites the previous data, but since the data is shorter than the original, there are still remnants of the original data. Does anyone have any idea what the best/most efficient way to delete that extra data is?
Here is a simplified example of what I'm trying to do:
fid = fopen('file.txt','w');
for i=1:10
fprintf(fid,'%i\r\t',i);
end
frewind(fid);
for i=3:5
fprintf(fid,'%i\r\t',i);
end
fprintf(fid,'EOF');
fclose(fid);
I've looked all over, but I can't seem to find the solution to my question. Any suggestions?
Without using any temp files, you can do the following:
fid = fopen('file.txt', 'wt');
for i=1:10
fprintf(fid, '%i\n', i);
end
frewind(fid);
for i=3:5
fprintf(fid, '%i\n', i);
end
pos = ftell(fid); % get current position in file
fclose(fid);
% read from begining to pos
fid = fopen('file.txt', 'r');
data = fread(fid, pos);
fclose(fid);
% overwite file with data read
fid = fopen('file.txt', 'w');
fwrite(fid, data);
fclose(fid);
Printing "EOF" won't work - nice try!
There are Unix system calls truncate and ftruncate that will do that, given either a file descriptor (truncate) or handle (ftruncate) in the first argument and a desired length in the second.
I'd try and see if Matlab supports ftruncate. Failing that... if worst came to worst you could copy-write the file to a new file, stopping and closing the new file when you hit what you consider the end of data.
To follow up on Carl Smotricz's suggestion of using two files, you can use MATLAB's DELETE and MOVEFILE commands to avoid system calls:
fid = fopen('file.txt','wt');
for i=1:10
fprintf(fid,'\t%i\r',i);
end
fclose(fid);
fid = fopen('file.txt','rt');
fidNew = fopen('fileNew.txt', 'wt');
for i = 1:2
s = fgetl(fid);
fprintf(fidNew, '%s\r', s);
end
for i=4:10
fprintf(fidNew, '\t%i\r', i);
end
fclose(fid);
fclose(fidNew);
delete('file.txt');
movefile('fileNew.txt', 'file.txt')