我已经阅读了几个使用 Cassandra c# 驱动程序实现手动分页的链接。
链接参考:
https://datastax.github.io/csharp-driver/features/paging/
我的要求:
我正在尝试获取所有不同分区键表单表的列表,该表的大小太大。
由于大小,Cassandra db 在检索它们或第一次执行查询之间抛出错误。现在假设它在获取 100000 个不同的分区键后失败,我将使用 Cassandra c# 驱动程序提供的 Paging 状态。
现在我正在保存最后一个可用页面状态,然后再未能记录文件并再次使用它从失败的地方继续。
我正在使用以下命令将分页状态保存到日志文件中:
Encoding.ASCII.GetString(pagingState);
并使用以下方法检索表单日志文件:
Encoding.ASCII.GetBytes(pagingState);
但是当我将它传递给.SetPagingState(pagingState)并执行查询时,它会抛出异常,例如:
java.lang.IllegalStateException:在前一个迭代器被完全消耗之前不能调用 hasNext()
在保存到文件之前和从文件中检索它们之后,我逐字节地比较了数组字节。字节数组中的几个值是不同的。我尝试使用 UIF8 编码但没有用。
注意: 当我传递字节数组而不进行转换时,它工作得很好。如果条件代码完美运行,我的意思是下面的内容。
if (pagingState != null)
{
GenerateInitialLogs(pagingState);
}
全功能:
private void BtnGetPrimaryKeys_Click(object sender, EventArgs e)
{
string fileContent = File.ReadAllText("D:/Logs/log.txt");
if(fileContent.Length > 0)
{
GenerateInitialLogs(Encoding.ASCII.GetBytes(fileContent));
}
else
{
GenerateInitialLogs(null);
}
}
private void Log(byte[] pagingState)
{
File.WriteAllText("D:/Logs/log.txt", Encoding.ASCII.GetString(pagingState));
}
private int GenerateInitialLogs(byte[] pagingState)
{
try
{
RowSet rowSet = BLL.SelectDistinctPrimaryKeys(pagingState);
List<PrimaryKey> distinctPrimaryKeys = new List<PrimaryKey>();
foreach (Row row in rowSet)
{
if (rowSet.PagingState != null) { pagingState = new byte[rowSet.PagingState.Length]; }
pagingState = rowSet.PagingState;
}
Log(pagingState)
if (pagingState != null)
{
GenerateInitialLogs(pagingState);
}
}
catch(Exception ex)
{
throw ex;
}
}
public static RowSet SelectDistinctPrimaryKeysFromTagReadings(byte[] pagingState)
{
try
{
// will execute on continuing after failing in between.
if (pagingState != null)
{
PreparedStatement preparedStatement = BLL.currentSession.Prepare("SELECT DISTINCT \"Url\",\"Id\" FROM \"Readings\" ");
BoundStatement boundStatement = preparedStatement.Bind();
IStatement istatement = boundStatement.SetAutoPage(false).SetPageSize(1000).SetPagingState(pagingState);
return BLL.currentSession.Execute(istatement);
}
else
{
PreparedStatement preparedStatement = BLL.currentSession.Prepare("SELECT DISTINCT \"Url\",\"Id\" FROM \"Readings\" ");
BoundStatement boundStatement = preparedStatement.Bind();
IStatement istatement = boundStatement.SetAutoPage(false).SetPageSize(1000);
return BLL.currentSession.Execute(istatement);
}
}
catch (Exception ex)
{
throw ex;
}
}
这个解决方案不是我想出来的。它由 Jorge Bay Gondra(datastax 的员工)完成。
原答案:
https://groups.google.com/a/lists.datastax.com/forum/#!topic/csharp-driver-user/4XWTXZC-hyI
解决方案:
无法将它们转换为 ASCII 或 UIF8 或任何编码,因为它们不代表文本。
使用这些函数将字节数组转换为十六进制,反之亦然。
public static string ByteArrayToHexaDecimalString(byte[] bytes)
{
StringBuilder stringBuilder = new StringBuilder(bytes.Length * 2);
foreach (byte b in bytes) { stringBuilder.AppendFormat("{0:x2}", b); }
return stringBuilder.ToString();
}
public static byte[] HexaDecimalStringToByteArray(String hexaDecimalString)
{
int NumberChars = hexaDecimalString.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
{
bytes[i / 2] = Convert.ToByte(hexaDecimalString.Substring(i, 2), 16);
}
return bytes;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句