【问题标题】:write and read from byte stream从字节流写入和读取
【发布时间】:2013-09-17 17:53:27
【问题描述】:

我有一个页面,用户可以在其中上传自己的 csv 或将值输入到列表框中,然后创建一个 csv(在后台)。无论以哪种方式创建 csv,我都需要通过字节流将该 csv 上传到我们的服务器。

我的问题是,当我创建 csv 时,我不应该创建临时文件,我应该能够写入流然后将其读回以进行上传。如何消除对临时文件的需求?

当前有效的代码(但使用临时文件):

try {
                string filename = DateTime.Now.ToString("MMddyyHmssf");
                filename = filename + ".csv";
                string directory = ConfigurationManager.AppSettings["TempDirectory"].ToString();
                path = Path.Combine(directory, filename);
                using (StreamWriter sw = File.CreateText(path)) {

                    foreach (ListItem item in this.lstAddEmailAddress.Items) {
                        sw.WriteLine(" , ," + item.ToString());
                    }
                }
            } catch (Exception ex) {
                string error = "Cannot create temp csv file used for importing users by email address.  Filepath: " + path + ".  FileException: " + ex.ToString();
                this.writeToLogs(error, 1338);
            }
        }
        // put here for testing the byte array being sent vs ready byte[] byteArray = System.IO.File.ReadAllBytes(path);
        myCsvFileStream = File.OpenRead(path);
        nFileLen = (int)myCsvFileStream.Length;

我试过了

Stream myCsvFileStream;
using (StreamWriter sw = new StreamWriter(myCsvFileStream)) {

                    foreach (ListItem item in this.lstAddEmailAddress.Items) {
                        sw.WriteLine(" , ," + item.ToString());

                    }
                }

但是由于 myCsvFileStream 没有被初始化(因为 stream 是一个静态类)它总是为 null。

这是我在创建 csv 后对数据(字节流)所做的操作。

byte[] file = new byte[nFileLen];
            myCsvFileStream.Read(file, 0, nFileLen);
            bool response = this.repositoryService.SaveUsers(this.SelectedAccount.Id, file, this.authenticatedUser.SessionToken.SessionId);
            myCsvFileStream.Close();

最后我使用StringBuilder 来创建我的csv 文件内容。然后得到其内容的字节数组并用它来填充我的共享流(我说共享是因为当用户输入他们自己的 CSV 文件时,它是一个HttpPostedFile,但是当通过 rest 调用将它发送到我们的服务器时(respositoryservices.saveusers ) 它使用与通过此方法相同的字节流)

StringBuilder csvFileString = new StringBuilder();

            sharedStreamForBatchImport = new MemoryStream();
            foreach (ListItem item in this.lstAddEmailAddress.Items) {
                csvFileString.Append(",," + item.ToString() + "\\r\\n");
            }

            //get byte array of the string
            byteArrayToBeSent = Encoding.ASCII.GetBytes(csvFileString.ToString());
            //set length for read
            byteArraySize = (int)csvFileString.Length;
            //read bytes into the sharedStreamForBatchImport (byte array)
            sharedStreamForBatchImport.Read(byteArrayToBeSent, 0, byteArraySize);

【问题讨论】:

  • 我可能不需要 read 调用。我应该能够将 getbytes 的返回设置为 sharedstreamforbatchimport。但那是另一天

标签: c# stream


【解决方案1】:

你想创建一个new MemoryStream()

【讨论】:

  • 对此不满意并回发。如果你有一个例子来节省我的时间,那就太棒了。我确定写入它与流写入器相同,但我将如何获得我的字节数组。不管怎样,谢谢
  • @owengerig 即:将Stream myCsvFileStream; 替换为Stream myCsvFileStream = new MemoryStream();
【解决方案2】:

这是我用来编写 CSV 文件的函数

    public static bool WriteCsvFile(string path, StringBuilder stringToWrite)
    {
        try
        {
            using (StreamWriter sw = new StreamWriter(path, false))         //false in ordre to overwrite the file if it already exists
            {
                sw.Write(stringToWrite);
                return true;
            }
        }
        catch (Exception)
        {
            return false;
        }
    }

stringToWrite 只是一个以这种方式创建的字符串:

    public static bool WriteCsvFile(string path, DataTable myData)
    {
        if (myData == null)
            return false;
        //Information about the table we read
        int nbRows = myData.Rows.Count;
        int nbCol = myData.Columns.Count;
        StringBuilder stringToWrite = new StringBuilder();

        //We get the headers of the table
        stringToWrite.Append(myData.Columns[0].ToString());
        for (int i = 1; i < nbCol; ++i)
        {
            stringToWrite.Append(",");
            stringToWrite.Append(myData.Columns[i].ToString());
        }
        stringToWrite.AppendLine();

        //We read the rest of the table
        for (int i = 0; i < nbRows; ++i)
        {
            stringToWrite.Append(myData.Rows[i][0].ToString());
            for (int j = 1; j < nbCol; ++j)
            {
                stringToWrite.Append(",");
                stringToWrite.Append(myData.Rows[i][j].ToString());
            }
            stringToWrite.AppendLine();
        }

        return WriteCsvFile(path, stringToWrite);
    }

【讨论】:

  • 我可以将 \r 和 \n 添加到字符串生成器字符串吗?我也可以获得构建字符串的字节数组吗?
  • 也许您需要转义来的字符,但没有理由不能添加 \r 或 \n。 (其实我用的是AppendLine(),所以我也不是很清楚)。对于字节数组,您可以执行类似 System.Text.Encoding.UTF8.GetBytes(stringToWrite.toString())
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-06
  • 1970-01-01
  • 1970-01-01
  • 2011-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多