FluentFTP icon indicating copy to clipboard operation
FluentFTP copied to clipboard

OpenAppend - You cannot modify the position of a FtpDataStream.

Open robinrodricks opened this issue 4 years ago • 4 comments
trafficstars

Same problem with FileZilla. FluentFTP version 33.1.6.

I'm taking my code from this example using (Stream ostream = conn.OpenAppend("/full/or/relative/path/to/file")) { try { ostream.Position = ostream.Length; var sr = new StreamWriter(ostream); sr.WriteLine(...); } finally { ostream.Close(); } } given here https://github.com/robinrodricks/FluentFTP/issues/52

System.InvalidOperationException HResult=0x80131509 Message=You cannot modify the position of a FtpDataStream. This property is updated as data is read or written to the stream. Source=FluentFTP StackTrace: at FluentFTP.FtpDataStream.set_Position(Int64 value) at VWUK.Utils.FtpService.FtpService.AppendMode(FtpClient ftp, String path, String data) in

Originally posted by @hrafnkel in https://github.com/robinrodricks/FluentFTP/issues/283#issuecomment-823149168

robinrodricks avatar Apr 20 '21 11:04 robinrodricks

Please use the new append API - UploadFile(.... FtpExists.Append) - if it does not work, tell me and I'll document it better

robinrodricks avatar Apr 20 '21 11:04 robinrodricks

I have tried UploadFile with Append. Creation works fine, but it does not append to a pre-existing file.

        private FtpStatus AppendMode(FtpClient ftp, string path, string data)
        {
            ftp.UploadDataType = FtpDataType.ASCII;

            // make a local temp file
            string fileName = "tempFile";
            File.AppendAllText(fileName, data);
            
            // upload file
            FtpStatus status = ftp.UploadFile(fileName,path,FtpRemoteExists.Append, false);

            // delete temp file
            File.Delete(fileName);

            return status;
        }

hrafnkel avatar Apr 20 '21 11:04 hrafnkel

Additional. The debug log

Fred: Debug: >         Connect()
Fred: Information: Status:   Connecting to [address]
Fred: Debug: Response: 220-FileZilla Server 0.9.60 beta
Response: 220-written by Tim Kosse ([email protected])
Fred: Information: Response: 220 Please visit https://filezilla-project.org/
Fred: Information: Status:   Detected FTP server: FileZilla
Fred: Information: Command:  AUTH TLS
Fred: Information: Response: 234 Using authentication type TLS
Fred: Information: Status:   FTPS Authentication Successful
Fred: Debug: Status:   Time to activate encryption: 0h 0m 0s.  Total Seconds: 0.1159128.
Fred: Information: Command:  USER [user]
Fred: Information: Response: 331 Password required for [user]
Fred: Information: Command:  PASS ***
Fred: Information: Response: 230 Logged on
Fred: Information: Command:  PBSZ 0
Fred: Information: Response: 200 PBSZ=0
Fred: Information: Command:  PROT P
Fred: Information: Response: 200 Protection level set to P
Fred: Information: Command:  FEAT
Fred: Debug: Response: 211-Features:
Response: MDTM
Response: REST STREAM
Response: SIZE
Response: MLST type*;size*;modify*;
Response: MLSD
Response: AUTH SSL
Response: AUTH TLS
Response: PROT
Response: PBSZ
Response: UTF8
Response: CLNT
Response: MFMT
Response: EPSV
Response: EPRT
Fred: Information: Response: 211 End
Fred: Information: Status:   Text encoding: System.Text.UTF8Encoding+UTF8EncodingSealed
Fred: Information: Command:  OPTS UTF8 ON
Fred: Information: Response: 202 UTF8 mode is always enabled. No need to send this command.
Fred: Information: Command:  SYST
Fred: Information: Response: 215 UNIX emulated by FileZilla
Fred: Debug: >         GetFileSize("/FTPTestHarness.csv")
Fred: Information: Command:  SIZE /FTPTestHarness.csv
Fred: Information: Response: 213 366
Fred: Debug: >         FileExists("/FTPTestHarness.csv")
Fred: Information: Command:  SIZE /FTPTestHarness.csv
Fred: Information: Response: 213 366
Fred: Information: Creating new file
Fred: Debug: >         UploadFile("tempFile", "/FTPTestHarness.csv", Append, False, None)
Fred: Debug: >         FileExists("/FTPTestHarness.csv")
Fred: Information: Command:  SIZE /FTPTestHarness.csv
Fred: Information: Response: 213 366
Fred: Debug: >         GetFileSize("/FTPTestHarness.csv")
Fred: Information: Command:  SIZE /FTPTestHarness.csv
Fred: Information: Response: 213 366
Fred: Debug: >         OpenAppend("/FTPTestHarness.csv", ASCII)
Fred: Information: Command:  TYPE A
Fred: Information: Response: 200 Type set to A
Fred: Debug: >         OpenPassiveDataStream(EPSV, "APPE /FTPTestHarness.csv", 0)
Fred: Information: Command:  EPSV
Fred: Information: Response: 229 Entering Extended Passive Mode (|||65261|)
Fred: Information: Status:   Connecting to [address]
Fred: Information: Command:  APPE /FTPTestHarness.csv
Fred: Information: Response: 150 Opening data channel for file upload to server of "/FTPTestHarness.csv", restarting at offset 366
Fred: Information: Status:   FTPS Authentication Successful
Fred: Debug: Status:   Time to activate encryption: 0h 0m 0s.  Total Seconds: 0.071649.
Fred: Debug: Status:   Disposing FtpSocketStream...
Fred: Information: Response: 226 Successfully transferred "/FTPTestHarness.csv"

hrafnkel avatar Apr 20 '21 12:04 hrafnkel

I'm having the same problem

aaa930811 avatar Aug 10 '22 09:08 aaa930811

I'm having the same problem too.

nkev avatar Dec 01 '22 01:12 nkev

Can I chime in on this issue?

I have tested the code posted above, using the current version of FluentFTP (V42.1.0). -> proftpd - fails, APPE not allowed, but could be configured to work -> vsftpd - works -> FileZilla V 1.4.0 - works

This code works and is the recommended approach

client.Connect(ftpProfile);

client.Config.UploadDataType = FtpDataType.ASCII;

// make a local temp file
string fileName = "tempFile";
string dateTimeString;
dateTimeString = DateTime.Now.ToString();
System.IO.File.AppendAllText(fileName, dateTimeString + Environment.NewLine);

// upload file
FtpStatus status = client.UploadFile(fileName, "tempfile", FtpRemoteExists.AddToEnd, false);

// delete temp file
System.IO.File.Delete(fileName);

This code works and is the recommended approach

First of all,

FtpStatus status = ftp.UploadFile(fileName,path,FtpRemoteExists.Append, false);

needed to be changed to

FtpStatus status = ftp.UploadFile(fileName,path,FtpRemoteExists.AddToEnd, false);

First execution works fine, the file is created.

01.12.2022 11:21:32

Second execution works fine, I can see the new text in the destination file.

01.12.2022 11:21:32
01.12.2022 11:21:43

@nkev So, I would like to know the following from you:

? FluentFTP version, target FTP server and version, code sample, debug log

and maybe we can clear this up.

If I use the following code, I can reproduce the problem. I also get the You cannot modifiy... exception:

This code does not work

			using (Stream ostream = client.OpenAppend("tempfile")) {
				try {
					ostream.Position = ostream.Length;
					var sr = new StreamWriter(ostream);
					sr.WriteLine(dateTimeString);
				}
				finally {
					ostream.Close();
				}
			}

This code does not work

The type of stream returned by OpenAppend(...) does not support setting a position as in

ostream.Position = ostream.Length;

and that is the reason you are getting this exception: Message=You cannot modify the position of a FtpDataStream. This property is updated as data is read or written to the stream.

If you change the code just a little bit, it works fine:

This code works

			using (Stream ostream = client.OpenAppend("tempfile")) {
				try {
					byte[] buf = Encoding.ASCII.GetBytes(dateTimeString);
					ostream.Write(buf, 0, buf.Length);
				}
				finally {
					ostream.Close();
					client.GetReply();
				}
			}

This code works

Note: OpenAppend(...) is declared as being obsolete, so using the code at the top of this post is to be preferred.

FanDjango avatar Dec 01 '22 10:12 FanDjango

I think everone has seen this by now - it will be mentioned in the FAQ section at some point in time,

FanDjango avatar Jan 05 '23 23:01 FanDjango