C#實現json壓縮和格式化
阿新 • • 發佈:2019-01-10
json作為常用資料檔案,為了傳輸的效率,在傳輸前要進行壓縮,而在傳輸後要進行格式化,以便閱讀。下面是使用C#完成的格式化和壓縮程式碼。
1 public static void Compress(string filein, string fileout, Encoding encoding) 2 { 3 using(StreamReader reader = new StreamReader(filein, encoding)) 4 { 5 using (StreamWriter writer = new StreamWriter(fileout, false, encoding)) 6 { 7 int ch = -1; 8 int lastch = -1; 9 bool isQuoteStart = false; 10 while ((ch = reader.Read()) > -1) 11 { 12 if ((char)lastch != '\\' && (char)ch == '\"') 13 { 14 if(!isQuoteStart) 15 { 16 isQuoteStart = true; 17 } 18 else 19 { 20 isQuoteStart = false; 21 } 22 } 23 if (!Char.IsWhiteSpace((char)ch) || isQuoteStart) 24 { 25 writer.Write((char)ch); 26 } 27 lastch = ch; 28 } 29 } 30 } 31 }
因為在json中"是用作隔離key和value的,而"又可以作為value中的一部分,所以在處理中要判斷是否是單獨的",還是作為隔離符號,所以要進行如上的判斷。
1 public static void Format(string filein, string fileout, Encoding encoding) 2 { 3 using (StreamReader reader = new StreamReader(filein, encoding)) 4 { 5 using (StreamWriter writer = new StreamWriter("temp", false, encoding)) 6 { 7 int ch = -1; 8 int lastch = -1; 9 bool isQuoteStart = false; 10 while ((ch = reader.Read()) > -1) 11 { 12 StringBuilder sb = new StringBuilder(); 13 switch ((char)ch) 14 { 15 case '{': 16 if (isQuoteStart) 17 { 18 sb.Append('{'); 19 } 20 else 21 { 22 sb.Append('{'); 23 if ((char)reader.Peek() != '}') 24 { 25 sb.Append(Environment.NewLine); 26 } 27 } 28 break; 29 case '}': 30 if (isQuoteStart) 31 { 32 sb.Append('}'); 33 } 34 else 35 { 36 if ((char)lastch != '{' && (char)lastch != '}') 37 { 38 sb.Append(Environment.NewLine); 39 } 40 sb.Append('}'); 41 if((char)reader.Peek() != ',') 42 { 43 sb.Append(Environment.NewLine); 44 } 45 } 46 break; 47 case '[': 48 if (isQuoteStart) 49 { 50 sb.Append('['); 51 } 52 else 53 { 54 sb.Append('['); 55 if ((char)reader.Peek() != ']') 56 { 57 sb.Append(Environment.NewLine); 58 } 59 } 60 break; 61 case ']': 62 if (isQuoteStart) 63 { 64 sb.Append(']'); 65 } 66 else 67 { 68 if ((char)lastch != '[' && (char)lastch != ']') 69 { 70 sb.Append(Environment.NewLine); 71 } 72 sb.Append(']'); 73 if ((char)reader.Peek() != ',' && (char)reader.Peek() != '}') 74 { 75 sb.Append(Environment.NewLine); 76 } 77 } 78 break; 79 case '\"': 80 if((char)lastch != '\\') 81 { 82 if (!isQuoteStart) 83 { 84 isQuoteStart = true; 85 } 86 else 87 { 88 isQuoteStart = false; 89 } 90 } 91 sb.Append("\""); 92 break; 93 case ':': 94 if (isQuoteStart) 95 { 96 sb.Append(':'); 97 } 98 else 99 { 100 sb.Append(':'); 101 sb.Append(" "); 102 } 103 break; 104 case ',': 105 if (isQuoteStart) 106 { 107 sb.Append(','); 108 } 109 else 110 { 111 sb.Append(','); 112 sb.Append(Environment.NewLine); 113 } 114 break; 115 case ' ': 116 if (isQuoteStart) 117 { 118 sb.Append(" "); 119 } 120 else 121 { 122 sb.Append(""); 123 sb.Append(Environment.NewLine); 124 } 125 break; 126 default: 127 sb.Append((char)ch); 128 break; 129 } 130 writer.Write(sb.ToString()); 131 lastch = ch; 132 } 133 } 134 } 135 136 using(StreamReader reader = new StreamReader("temp", encoding)) 137 { 138 using (StreamWriter writer = new StreamWriter(fileout, false, encoding)) 139 { 140 string str = null; 141 142 int nspace = 0; 143 string space = " "; 144 while ((str = reader.ReadLine()) != null) 145 { 146 if (str.EndsWith("},")) 147 { 148 nspace--; 149 } 150 StringBuilder sb = new StringBuilder(); 151 for(int i=0; i<(str.EndsWith("],") || (str.EndsWith("}") && !str.EndsWith("{}")) || str.EndsWith("]") ? nspace-1:nspace); i++) 152 { 153 sb.Append(space); 154 } 155 sb.Append(str); 156 writer.WriteLine(sb); 157 if(!(str.EndsWith("{}") || str.EndsWith("[]"))) 158 { 159 if (str.StartsWith("{") || str.EndsWith("{") || 160 str.EndsWith("[")) 161 { 162 nspace++; 163 } 164 if (str.EndsWith("}") || str.EndsWith("]")) 165 { 166 nspace--; 167 } 168 } 169 } 170 } 171 } 172 } 173
對"的考慮同compress,但格式化的話需要考慮到縮排,而放到一起考慮比較麻煩,所以先進行了格式化,然後在處理縮排,這樣就簡化了邏輯。