Write to text file

9 ビュー (過去 30 日間)
Martijn Geelen
Martijn Geelen 2019 年 4 月 14 日
回答済み: Walter Roberson 2019 年 4 月 14 日
Hi,
I am opening an existing text file, read the file data, make several changes to data in the file. Thereafter i am trying to write back the changed data. However, the original data is still in the file after running the code. I tested writing the data to an empty text file called 'test.txt' but this one remains empty as well. Can someone tell me why fprintf(fid,'%s\n',C_new{:}); does not work in the code below? C_new is a 19x1 cell (see attachment).
if N_Locations > 1
if length(char(ReadSKU))> 8
%simulation cannot handle file names longer than 8
%characters and those were replace to names with 'temp':
newname = strcat('temp',num2str(LongName))
LongName = LongName+1;
try
fid = fopen(['C:\TdKSimulatie\Stocksim\' char(newname) '.sim']);
C = textscan(fid, '%s', 'delimiter', '\n');%,'HeaderLines',5);
catch
NotFound = 1;
% ME
% idSegLast = regexp(ME1.identifier, '(?<=:)\w+$', 'match');
% fprintf('Unable to access file %s\n', filename);
% rethrow(ME2)
end
else
try
fid = fopen(['C:\TdKSimulatie\Stocksim\' char(ReadSKU) '.sim']);
C = textscan(fid, '%s', 'delimiter', '\n');%,'HeaderLines',5);
catch
NotFound=1;
% ME2
% idSegLast = regexp(ME1.identifier, '(?<=:)\w+$', 'match');
% fprintf('Unable to access file %s\n', filename);
% rethrow(ME2)
end
end
if NotFound == 0
%HERE I MAKE SEVERAL CHANGES TO THE DATA.
%HERE I MAKE SEVERAL CHANGES TO THE DATA.
%HERE I MAKE SEVERAL CHANGES TO THE DATA.
%HERE I MAKE SEVERAL CHANGES TO THE DATA.
end
% write adaptations back to .sim file:
%fclose(fid);
%fid = fopen(['C:\TdKSimulatie\Stocksim\test.txt','w']);
fprintf(fid,'%s\n',C_new{:});
fclose(fid);
end

採用された回答

Stephen23
Stephen23 2019 年 4 月 14 日
編集済み: Stephen23 2019 年 4 月 14 日
You fopen-ed the file in read mode and not write mode (because the default mode is read mode and you did not specify any other mode). If you want to write to a file then you need to open it in write mode (most commonly) or append mode (less common):
... = fopen(..., 'wt');
% ^^^^ you forgot to open the file in WRITE MODE!
Read the fopen help to know more about the different modes.
You seem to want to handle file errors: for that I strongly recommend that you obtain the second output message from fopen:
[fid,msg] = fopen(...)
assert(fid>=3,msg)

その他の回答 (2 件)

Stephan
Stephan 2019 年 4 月 14 日
編集済み: Stephan 2019 年 4 月 14 日
Hi,
note the permission argument for fopen. The way you call the files is read only permission.
Best regards
Stephan

Walter Roberson
Walter Roberson 2019 年 4 月 14 日
It is possible to open a file in a way that permits a mix of reading and writing. You need to be careful with the permissions to ensure that you can write at the current position rather than having all writes automatically go to the end of file (which changes the idea of where the current input position is!), but it is possible to do.
However, on all file systems that MATLAB is supported on, it is not possible to insert or remove text in the middle of a text file and have the file automatically adjust. That kind of work requires line-oriented file systems such as DEC's RSX-11 and VMS "Record Management Services" (RMS) https://en.wikipedia.org/wiki/Record_Management_Services, or fixed-width records such as were common on IBM's MVS. MATLAB was, at one time, implemented on DEC VMS, but it was never implemented in terms of RMS calls so it never supported this facility. I thought I had read that MATLAB was, at one time, implemented on IBM MVS, but at present I cannot find any evidence of that.
Anyhow, this is not an limitation of MATLAB as such: it is a limitation of how files are implemented by operating systems, as streams of bytes, rather than as "lines".
It is possible to replace text within a line with exactly the same amount of text. Replacing an end-of-line in a text file has results that are formally undefined by people who write international standards: it is permitted in the standards for an end-of-line be written as one character fewer or one character more than what was read in. When multibyte character is in effect in the text file, that could be up to 4 bytes difference.
If you wish to replace text with more text than is already present, then in text files, the only way is algorithms that have the effect of reading to end of file and writing it out again "delayed" by the number of inserted bytes.
If you wish to replace text with less text than is already present, then although you could read ahead and move bytes "forward" relative to where they were originally in the file, when you get to the end of where you want to write, there are still more bytes in the file. International standards define an operation to permit files to be truncated (discard everything after a certain point), but MATLAB does not supply any interface for that operation. Therefore in MATLAB, if you want to make a file shorter than it currently is, you have to resort to opening a new output file and copying through what you want to see there, closing files, and moving the new file in place of the existing file.
So... it is a lot easier to just not try to update a text file, and to instead create a new text file with the content you want.
Your existing code has a commented out fclose() / fopen() with 'w', followed by writing out the modified content that you read in. That works, but has a couple of considerations:
  • you are on MS Windows and are opening a text file for 'w', which is binary form. Each \n you write will be output as a linefeed only, with no carriage return. That works fine for most newer programs, but it is a problem for old programs such as Notepad, which still expects to see carriage returns. If there is any possibility that the user might expect to use an old program with the file, then use 'wt' instead of 'w' so that carriage returns are also output each time a newline is seen in the output. (Do not do this if you are writing any binary content!)
  • If something goes wrong in the writing process, such as disk full or Blue Screen of Death, then you have lost the original file, because opening for 'w' discards the content. You had the new content in memory, but you cannot guarantee that you will be able to write the new content to the file. Therefore unless you have a backup copy of the file, it is safer to write to a different file that you can then substitute for the original file. International standards define operating system "move file" operations as "atomic" (guarantee that even if there is a power failure, the file will either be intact in the old location or in the new location.)

カテゴリ

Help Center および File ExchangeLow-Level File I/O についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by