Я не мог понять, почему popen / pclose отсутствует в Codeblocks / MinGW. Поэтому я работал над проблемой, используя вместо этого CreateProcess () и CreatePipe (). Вот решение, которое сработало для меня:
//C++11
#include <cstdio>
#include <iostream>
#include <windows.h>
#include <cstdint>
#include <deque>
#include <string>
#include <thread>
using namespace std;
int SystemCapture(
string CmdLine, //Command Line
string CmdRunDir, //set to '.' for current directory
string& ListStdOut, //Return List of StdOut
string& ListStdErr, //Return List of StdErr
uint32_t& RetCode) //Return Exit Code
{
int Success;
SECURITY_ATTRIBUTES security_attributes;
HANDLE stdout_rd = INVALID_HANDLE_VALUE;
HANDLE stdout_wr = INVALID_HANDLE_VALUE;
HANDLE stderr_rd = INVALID_HANDLE_VALUE;
HANDLE stderr_wr = INVALID_HANDLE_VALUE;
PROCESS_INFORMATION process_info;
STARTUPINFO startup_info;
thread stdout_thread;
thread stderr_thread;
security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
security_attributes.bInheritHandle = TRUE;
security_attributes.lpSecurityDescriptor = nullptr;
if (!CreatePipe(&stdout_rd, &stdout_wr, &security_attributes, 0) ||
!SetHandleInformation(stdout_rd, HANDLE_FLAG_INHERIT, 0)) {
return -1;
}
if (!CreatePipe(&stderr_rd, &stderr_wr, &security_attributes, 0) ||
!SetHandleInformation(stderr_rd, HANDLE_FLAG_INHERIT, 0)) {
if (stdout_rd != INVALID_HANDLE_VALUE) CloseHandle(stdout_rd);
if (stdout_wr != INVALID_HANDLE_VALUE) CloseHandle(stdout_wr);
return -2;
}
ZeroMemory(&process_info, sizeof(PROCESS_INFORMATION));
ZeroMemory(&startup_info, sizeof(STARTUPINFO));
startup_info.cb = sizeof(STARTUPINFO);
startup_info.hStdInput = 0;
startup_info.hStdOutput = stdout_wr;
startup_info.hStdError = stderr_wr;
if(stdout_rd || stderr_rd)
startup_info.dwFlags |= STARTF_USESTDHANDLES;
// Make a copy because CreateProcess needs to modify string buffer
char CmdLineStr[MAX_PATH];
strncpy(CmdLineStr, CmdLine.c_str(), MAX_PATH);
CmdLineStr[MAX_PATH-1] = 0;
Success = CreateProcess(
nullptr,
CmdLineStr,
nullptr,
nullptr,
TRUE,
0,
nullptr,
CmdRunDir.c_str(),
&startup_info,
&process_info
);
CloseHandle(stdout_wr);
CloseHandle(stderr_wr);
if(!Success) {
CloseHandle(process_info.hProcess);
CloseHandle(process_info.hThread);
CloseHandle(stdout_rd);
CloseHandle(stderr_rd);
return -4;
}
else {
CloseHandle(process_info.hThread);
}
if(stdout_rd) {
stdout_thread=thread([&]() {
DWORD n;
const size_t bufsize = 1000;
char buffer [bufsize];
for(;;) {
n = 0;
int Success = ReadFile(
stdout_rd,
buffer,
(DWORD)bufsize,
&n,
nullptr
);
printf("STDERR: Success:%d n:%d\n", Success, (int)n);
if(!Success || n == 0)
break;
string s(buffer, n);
printf("STDOUT:(%s)\n", s.c_str());
ListStdOut += s;
}
printf("STDOUT:BREAK!\n");
});
}
if(stderr_rd) {
stderr_thread=thread([&]() {
DWORD n;
const size_t bufsize = 1000;
char buffer [bufsize];
for(;;) {
n = 0;
int Success = ReadFile(
stderr_rd,
buffer,
(DWORD)bufsize,
&n,
nullptr
);
printf("STDERR: Success:%d n:%d\n", Success, (int)n);
if(!Success || n == 0)
break;
string s(buffer, n);
printf("STDERR:(%s)\n", s.c_str());
ListStdOut += s;
}
printf("STDERR:BREAK!\n");
});
}
WaitForSingleObject(process_info.hProcess, INFINITE);
if(!GetExitCodeProcess(process_info.hProcess, (DWORD*) &RetCode))
RetCode = -1;
CloseHandle(process_info.hProcess);
if(stdout_thread.joinable())
stdout_thread.join();
if(stderr_thread.joinable())
stderr_thread.join();
CloseHandle(stdout_rd);
CloseHandle(stderr_rd);
return 0;
}
int main()
{
int rc;
uint32_t RetCode;
string ListStdOut;
string ListStdErr;
cout << "STARTING.\n";
rc = SystemCapture(
"C:\\Windows\\System32\\ipconfig.exe", //Command Line
".", //CmdRunDir
ListStdOut, //Return List of StdOut
ListStdErr, //Return List of StdErr
RetCode //Return Exit Code
);
if (rc < 0) {
cout << "ERROR: SystemCapture\n";
}
cout << "STDOUT:\n";
cout << ListStdOut;
cout << "STDERR:\n";
cout << ListStdErr;
cout << "Finished.\n";
cout << "Press Enter to Continue";
cin.ignore();
return 0;
}
Вы не можете и не должны полагаться на упорядочение элементов в объекте JSON.
Из спецификации JSON в http://www.json.org/
Объект является неупорядоченным набором пар имя / значение
. Как следствие, библиотеки JSON могут изменять порядок элементов по своему усмотрению. Это не ошибка.
Как все говорят вам, JSON не поддерживает «последовательность», но массив делает, может быть, это может вас убедить: Упорядоченный JSONObject
Загрузите «json simple 1.1 jar» из этого https://code.google.com/p/json-simple/downloads/detail?name=json_simple-1.1.jar&can=2&q=
И добавьте файл jar в вашу папку lib
с помощью JSONValue, вы можете преобразовать LinkedHashMap в json string
для получения дополнительной информации нажмите здесь http://androiddhina.blogspot.in/2015/09/ordered-json-string-in-android.html
Основная цель здесь - отправить упорядоченный объект JSON в качестве ответа. Для этого нам не нужен javax.json.JsonObject. Мы могли бы создать упорядоченный json как строку. Сначала создайте LinkedHashMap со всеми парами значений ключей в требуемом порядке. Затем сгенерируйте json в строке, как показано ниже. Это намного проще с Java 8.
public Response getJSONResponse() {
Map<String, String> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("A", "1");
linkedHashMap.put("B", "2");
linkedHashMap.put("C", "3");
String jsonStr = linkedHashMap.entrySet().stream()
.map(x -> "\"" + x.getKey() + "\":\"" + x.getValue() + "\"")
.collect(Collectors.joining(",", "{", "}"));
return Response.ok(jsonStr).build();
}
Ответ возврата этой функцией будет следующим: {"A":"1","B":"2","C":"3"}
Я согласен с другими ответами. Вы не можете полагаться на порядок элементов JSON.
Однако, если нам нужно иметь упорядоченное JSON, одним из решений может быть подготовка объекта LinkedHashMap с элементами и преобразование его в JSONObject.
@Test
def void testOrdered() {
Map obj = new LinkedHashMap()
obj.put("a", "foo1")
obj.put("b", new Integer(100))
obj.put("c", new Double(1000.21))
obj.put("d", new Boolean(true))
obj.put("e", "foo2")
obj.put("f", "foo3")
obj.put("g", "foo4")
obj.put("h", "foo5")
obj.put("x", null)
JSONObject json = (JSONObject) obj
logger.info("Ordered Json : %s", json.toString())
String expectedJsonString = """{"a":"foo1","b":100,"c":1000.21,"d":true,"e":"foo2","f":"foo3","g":"foo4","h":"foo5"}"""
assertEquals(expectedJsonString, json.toString())
JSONAssert.assertEquals(JSONSerializer.toJSON(expectedJsonString), json)
}
Обычно порядок не сохраняется, как показано ниже.
@Test
def void testUnordered() {
Map obj = new HashMap()
obj.put("a", "foo1")
obj.put("b", new Integer(100))
obj.put("c", new Double(1000.21))
obj.put("d", new Boolean(true))
obj.put("e", "foo2")
obj.put("f", "foo3")
obj.put("g", "foo4")
obj.put("h", "foo5")
obj.put("x", null)
JSONObject json = (JSONObject) obj
logger.info("Unordered Json : %s", json.toString(3, 3))
String unexpectedJsonString = """{"a":"foo1","b":100,"c":1000.21,"d":true,"e":"foo2","f":"foo3","g":"foo4","h":"foo5"}"""
// string representation of json objects are different
assertFalse(unexpectedJsonString.equals(json.toString()))
// json objects are equal
JSONAssert.assertEquals(JSONSerializer.toJSON(unexpectedJsonString), json)
}
Вы также можете проверить мой пост: http://www.flyingtomoon.com/2011/04/preserving-order -в-json.html
JSONObject.toJSONString(obj)
. В противном случае я получил ошибку преобразования как @Ernest, упомянутую выше.
– Tricky12
22 July 2015 в 17:44
org.json.JSONObject
не имеет этого метода. 2.) Метод, который, кажется, может сделать трюк org.json.JSONObject.valueToString(obj)
, НЕ работает, поскольку он делает это внутри: new JSONObject(map).toString()
, который снова использует HashMap
, а не LinkedHashMap
внутри: this.map = new HashMap<String, Object>();
– Frederic Leitenberger
27 October 2017 в 10:13
Java
, но он не будет работать в Java
по нескольким причинам. Помимо очевидных синтаксических ошибок, таких как отсутствие «;», ключевое слово «def» не существует в Java и, наконец: JSONObject json = (JSONObject) obj
→ A HashMap
нельзя передать в JSONObject
→ ClassCastException
. И еще одно: ссылка в конце вашего сообщения приводит к рекламной странице (неработающая ссылка?).
– Frederic Leitenberger
27 October 2017 в 11:44
toJSONString()
- это метод, если у вас есть библиотека org.json.simple
. Это было доступно мне в моей среде IDE. Я не смотрел на это уже пару лет, поэтому я не знаю, как еще помочь.
– Tricky12
27 October 2017 в 19:26
Объекты JavaScript и JSON не имеют способа установить порядок для ключей. Вы можете получить это прямо в Java (я не знаю, как работают объекты Java), но если это будет веб-клиент или другой потребитель JSON, нет никакой гарантии относительно порядка ключей.
Для Java-кода создайте класс POJO для вашего объекта вместо JSONObject. и используйте JSONEncapsulator для вашего класса POJO. таким образом, порядок элементов зависит от порядка геттер-сеттеров в вашем классе POJO. например. Класс POJO будет как
Class myObj{
String userID;
String amount;
String success;
// getter setters in any order that you want
, и вам нужно отправить свой json-объект в ответ
JSONContentEncapsulator<myObj> JSONObject = new JSONEncapsulator<myObj>("myObject");
JSONObject.setObject(myObj);
return Response.status(Status.OK).entity(JSONObject).build();
. Ответ этой строки будет
{myObject: {// атрибуты упорядочиваются так же, как и порядок настройки получателя.}}
из примера lemiorhan, который я могу решить, просто изменив некоторую строку использования кода lemiorhan:
JSONObject json = new JSONObject(obj);
вместо этого:
JSONObject json = (JSONObject) obj
, поэтому в моем тестовом коде:
Map item_sub2 = new LinkedHashMap();
item_sub2.put("name", "flare");
item_sub2.put("val1", "val1");
item_sub2.put("val2", "val2");
item_sub2.put("size",102);
JSONArray itemarray2 = new JSONArray();
itemarray2.add(item_sub2);
itemarray2.add(item_sub2);//just for test
itemarray2.add(item_sub2);//just for test
Map item_sub1 = new LinkedHashMap();
item_sub1.put("name", "flare");
item_sub1.put("val1", "val1");
item_sub1.put("val2", "val2");
item_sub1.put("children",itemarray2);
JSONArray itemarray = new JSONArray();
itemarray.add(item_sub1);
itemarray.add(item_sub1);//just for test
itemarray.add(item_sub1);//just for test
Map item_root = new LinkedHashMap();
item_root.put("name", "flare");
item_root.put("children",itemarray);
JSONObject json = new JSONObject(item_root);
System.out.println(json.toJSONString());
u может сохранить порядок, если u использует JsonObject, принадлежащий com.google.gson: D
JsonObject responseObj = new JsonObject();
responseObj.addProperty("userid", "User 1");
responseObj.addProperty("amount", "24.23");
responseObj.addProperty("success", "NO");
Использование этого JsonObject даже не требует использования Map & lt;>
CHEERS !!!
Для тех, кто использует maven, попробуйте com.github.tsohr / json
<!-- https://mvnrepository.com/artifact/com.github.tsohr/json -->
<dependency>
<groupId>com.github.tsohr</groupId>
<artifactId>json</artifactId>
<version>0.0.1</version>
</dependency>
Он разветвляется из JSON-java но переключите реализацию своей карты с LinkedHashMap , который отмечен выше.
Реальный ответ можно найти в спецификации, json неупорядочен. Однако, как человек, я приказал своим элементам в порядке важности. Мало того, что это более логичный способ, было легче читать. Может быть, автору спецификации никогда не приходилось читать JSON, я делаю .. Итак, вот исправить:
/**
* I got really tired of JSON rearranging added properties.
* Specification states:
* "An object is an unordered set of name/value pairs"
* StackOverflow states:
* As a consequence, JSON libraries are free to rearrange the order of the elements as they see fit.
* I state:
* My implementation will freely arrange added properties, IN SEQUENCE ORDER!
* Why did I do it? Cause of readability of created JSON document!
*/
private static class OrderedJSONObjectFactory {
private static Logger log = Logger.getLogger(OrderedJSONObjectFactory.class.getName());
private static boolean setupDone = false;
private static Field JSONObjectMapField = null;
private static void setupFieldAccessor() {
if( !setupDone ) {
setupDone = true;
try {
JSONObjectMapField = JSONObject.class.getDeclaredField("map");
JSONObjectMapField.setAccessible(true);
} catch (NoSuchFieldException ignored) {
log.warning("JSONObject implementation has changed, returning unmodified instance");
}
}
}
private static JSONObject create() {
setupFieldAccessor();
JSONObject result = new JSONObject();
try {
if (JSONObjectMapField != null) {
JSONObjectMapField.set(result, new LinkedHashMap<>());
}
}catch (IllegalAccessException ignored) {}
return result;
}
}
JSONObject
поле map
является окончательным, но, похоже, оно работает. Если это не сработает, это дополнение должно помочь преодолеть final
: stackoverflow.com/a/3301720/1520422
– Frederic Leitenberger
27 October 2017 в 12:03