It turned out the order of
$ftp = [System.Net.FtpWebRequest]::Create($fileRemotePath)
and $ftprespsonse = [System.Net.FtpWebResponse]$ftp.GetResponse()
and $rs = $ftp.GetRequestStream()
messes up the stuff. By running the code line by line, I find that the empty file is created at the first appearance of the $ftp.GetResponse() , after that, the full file is created on line $ftp.GetRequestStream()
therefore, I will move the first GetResponse() to after the GetRequestStream()