2013-09-17 3 views
0

У меня есть страница, на которой пользователь может загрузить свой собственный 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 не инициализируется (потому что поток является статическим классом) всегда нуль ,

Вот что я делаю с данными (поток байтов) после создания 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, но при отправке его на наш сервер с помощью остального вызова (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); 
+0

Возможно, мне не нужен звонок для чтения. я должен иметь возможность просто установить возврат из getbytes в sharedstreamforbatchimport. но это на другой день –

ответ

2

Вы хотите создать new MemoryStream()

+0

плохо работать над этим и после. если у вас есть пример, чтобы сэкономить время, которое было бы потрясающе. Я уверен, что запись на него аналогична записи потока, но как я могу получить свой байтовый массив. в любом случае спасибо –

+0

@owengerig ie: замените 'Stream myCsvFileStream'' на 'Stream myCsvFileStream = new MemoryStream();'. –

0

Вот функция, я использую для записи 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); 
    } 
+0

Могу ли я добавить \ r и \ n в строку построителя строк? также я смогу получить массив байтов встроенной строки? –

+0

Возможно, вам нужно будет сбежать от персонажей, но нет причин, по которым вы не сможете добавить \ r или \ n. (Фактически, я использую AppendLine(), поэтому я действительно не знаю). Для массива байтов вы можете сделать что-то вроде System.Text.Encoding.UTF8.GetBytes (stringToWrite.toString()) –

Смежные вопросы